suitestore_task_manager.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 985 行 · 第 1/2 页

C
985
字号
/* * * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. *//** * @file * * @ingroup AMS * * This is reference implementation of the Task Manager API of the MIDlet * suite storage subsystem. * The functions implemented in this file need not to be ported if using NAMS. */#include <kni.h>#include <string.h>#include <midpInit.h>#include <midpStorage.h>#include <midpRMS.h>#include <push_server_export.h>#include <pcsl_memory.h>#include <imageCache.h>#include <suitestore_intern.h>#include <suitestore_locks.h>#include <suitestore_otanotifier_db.h>#include <suitestore_listeners.h>#if ENABLE_ICON_CACHE#include <suitestore_icon_cache.h>#endifstatic MIDPError change_enabled_state(SuiteIdType suiteId, jboolean enabled);/* ------------------------------------------------------------ *//*                           Public API                         *//* ------------------------------------------------------------ *//** * Retrieves the number of installed midlet suites. * * @param pNumOfSuites [out] pointer to variable to accept the number of suites * * @returns error code (ALL_OK if no errors) */MIDPErrormidp_get_number_of_suites(int* pNumOfSuites) {    MIDPError status;    char* pszError;    do {        /*         * This is a public API which can be called without the VM running         * so we need automatically init anything needed, to make the         * caller's code less complex.         *         * Initialization is performed in steps so that we do use any         * extra resources such as the VM for the operation being performed.         */        if (midpInit(LIST_LEVEL) != 0) {            status = OUT_OF_MEMORY;            break;        }        /* load _suites.dat */        status = read_suites_data(&pszError);        if (status == ALL_OK) {#if ENABLE_DYNAMIC_COMPONENTS            MidletSuiteData* pData = g_pSuitesData;            int num = 0;            /* walk through the linked list */            while (pData != NULL) {                if (pData->type == COMPONENT_REGULAR_SUITE) {                    num++;                }                pData = pData->nextEntry;            }            *pNumOfSuites = num;#else            *pNumOfSuites = g_numberOfSuites;#endif /* ENABLE_DYNAMIC_COMPONENTS */        } else {            storageFreeError(pszError);        }    } while(0);    return status;}#if ENABLE_DYNAMIC_COMPONENTS/** * Retrieves the number of the installed components belonging * to the given midlet suite. * * @param suiteId          [in]  ID of the MIDlet suite the information about *                               whose components must be retrieved * @param pNumOfComponents [out] pointer to variable to accept the number *                               of components * * @returns error code (ALL_OK if no errors) */MIDPErrormidp_get_number_of_components(SuiteIdType suiteId, int* pNumOfComponents) {    MIDPError status;    char* pszError;    MidletSuiteData* pData;    int n = 0;    do {        if (midpInit(LIST_LEVEL) != 0) {            status = OUT_OF_MEMORY;            break;        }        /* load _suites.dat */        status = read_suites_data(&pszError);        if (status != ALL_OK) {            storageFreeError(pszError);            break;        }        pData = g_pSuitesData;        /* walk through the linked list */        while (pData != NULL) {            if (pData->suiteId == suiteId && pData->type == COMPONENT_DYNAMIC) {                n++;            }            pData = pData->nextEntry;        }        *pNumOfComponents = n;    } while(0);    return status;}#endif /* ENABLE_DYNAMIC_COMPONENTS *//** * Disables a suite given its suite ID. * <p> * The method does not stop the suite if is in use. However any future * attepts to run a MIDlet from this suite while disabled should fail. * * @param suiteId  ID of the suite * * @return ALL_OK if no errors, *         NOT_FOUND if the suite does not exist, *         SUITE_LOCKED if the suite is locked, *         IO_ERROR if IO error has occured, *         OUT_OF_MEMORY if out of memory */MIDPErrormidp_disable_suite(SuiteIdType suiteId) {    return change_enabled_state(suiteId, KNI_FALSE);}/** * Enables a suite given its suite ID. * <p> * The method does update an suites that are currently loaded for * settings or of application management purposes. * * @param suiteId  ID of the suite * * @return ALL_OK if no errors, *         NOT_FOUND if the suite does not exist, *         SUITE_LOCKED if the suite is locked, *         IO_ERROR if IO error has occured, *         OUT_OF_MEMORY if out of memory */MIDPErrormidp_enable_suite(SuiteIdType suiteId) {    return change_enabled_state(suiteId, KNI_TRUE);}/** * Get the list installed of MIDlet suite IDs. * * Note that memory for the suite IDs is allocated by the callee, * and the caller is responsible for freeing it using midp_free_suite_ids(). * * @param ppSuites empty array of jints to fill with suite IDs * @param pNumOfSuites [out] pointer to variable to accept the number * of suites in the returned array * * @returns error code: ALL_OK if no errors, *          OUT_OF_MEMORY if for out of memory, *          IO_ERROR if an IO error */MIDPErrormidp_get_suite_ids(SuiteIdType** ppSuites, int* pNumOfSuites) {    MIDPError status;    char* pszError;    SuiteIdType* pSuiteIds;    MidletSuiteData* pData;    int numberOfSuites = 0;#if ENABLE_DYNAMIC_COMPONENTS    int numberOfEntries = 0;#endif    *ppSuites = NULL;    *pNumOfSuites = 0;    /*     * This is a public API which can be called without the VM running     * so we need automatically init anything needed, to make the     * caller's code less complex.     *     * Initialization is performed in steps so that we do use any     * extra resources such as the VM for the operation being performed.     */    if (midpInit(LIST_LEVEL) != 0) {        return OUT_OF_MEMORY;    }    /* load _suites.dat */    status = read_suites_data(&pszError);    storageFreeError(pszError);    if (status != ALL_OK) {        return status;    }    if (!g_numberOfSuites) {        /* there are no installed suites */        return ALL_OK;    }    pData = g_pSuitesData;    /* allocate a memory for the IDs */    pSuiteIds = pcsl_mem_malloc(g_numberOfSuites * sizeof(SuiteIdType));    if (pSuiteIds == NULL) {        return OUT_OF_MEMORY;    }    /* walk through the linked list collecting suite IDs */    while (pData != NULL) {#if ENABLE_DYNAMIC_COMPONENTS        if (pData->type == COMPONENT_REGULAR_SUITE) {#endif            pSuiteIds[numberOfSuites] = pData->suiteId;            numberOfSuites++;#if ENABLE_DYNAMIC_COMPONENTS        }        numberOfEntries++;#endif        pData = pData->nextEntry;    }#if ENABLE_DYNAMIC_COMPONENTS    if (numberOfEntries != g_numberOfSuites) {#else    if (numberOfSuites != g_numberOfSuites) {#endif        /*         * This should not happen: it means that something is wrong with         * the list of structures containing the midlet suites information.         */        pcsl_mem_free(pSuiteIds);        return IO_ERROR;    }    *ppSuites = pSuiteIds;    *pNumOfSuites = numberOfSuites;    return ALL_OK;}/** * Frees a list of suite IDs. * * @param pSuiteIds point to an array of suite IDs * @param numberOfSuites number of elements in pSuites */voidmidp_free_suite_ids(SuiteIdType* pSuiteIds, int numberOfSuites) {    (void)numberOfSuites;    pcsl_mem_free(pSuiteIds);}/** * Removes a software package given its suite ID * <p> * If the component is in use it must continue to be available * to the other components that are using it.  The resources it * consumes must not be released until it is not in use. * * @param suiteId ID of the suite * * @return ALL_OK if no errors, *         NOT_FOUND if the suite does not exist, *         SUITE_LOCKED if the suite is locked, *         BAD_PARAMS this suite cannot be removed */MIDPErrormidp_remove_suite(SuiteIdType suiteId) {    pcsl_string filename;    char* pszError;    pcsl_string suiteRoot;    MIDPError status;    int operationStarted = 0;    void* fileIteratorHandle = NULL;    MidpProperties properties;    pcsl_string* pproperty;    MidletSuiteData* pData = NULL;    pcsl_string filenameBase;    lockStorageList *node = NULL;    /* get the filename base from the suite id */    status = build_suite_filename(suiteId, &PCSL_STRING_EMPTY,                                           &filenameBase);    if (status != ALL_OK) {        return status;    }    node = find_storage_lock(suiteId);    if (node != NULL) {        if (node->update != KNI_TRUE) {            return SUITE_LOCKED;        }    }    /*     * This is a public API which can be called without the VM running     * so we need automatically init anything needed, to make the     * caller's code less complex.     *     * Initialization is performed in steps so that we do use any     * extra resources such as the VM for the operation being performed.     */    if (midpInit(REMOVE_LEVEL) != 0) {        return OUT_OF_MEMORY;    }    do {        int rc; /* return code for rmsdb_... and storage_... */        /* load _suites.dat */        status = read_suites_data(&pszError);        storageFreeError(pszError);        if (status != ALL_OK) {            break;        }        /* check that the suite exists and it is not a preloaded one */        pData = get_suite_data(suiteId);        if (pData == NULL) {            status = NOT_FOUND;            break;        }        /* notify the listeners that we starting to remove the suite */        operationStarted = 1;        suite_listeners_notify(SUITESTORE_LISTENER_TYPE_REMOVE,            SUITESTORE_OPERATION_START, ALL_OK, pData);        if (pData->type == COMPONENT_PREINSTALLED_SUITE) {            status = BAD_PARAMS;            break;        }        status = begin_transaction(TRANSACTION_REMOVE_SUITE, suiteId, NULL);        if (status != ALL_OK) {            return status;        }        /*         * Remove the files         * Call the native RMS method to remove the RMS data.         * This function call is needed for portability         */        rc = rmsdb_remove_record_stores_for_suite(&filenameBase, suiteId);        if (rc == KNI_FALSE) {            status = SUITE_LOCKED;            break;        }        pushdeletesuite(suiteId);        /*         * If there is a delete notify property, add the value to the delete         * notify URL list.         */        properties = midp_get_suite_properties(suiteId);        if (properties.numberOfProperties > 0) {            pproperty = midp_find_property(&properties, &DELETE_NOTIFY_PROP);            if (pcsl_string_length(pproperty) > 0) {                midpAddDeleteNotification(suiteId, pproperty);            }            pproperty = midp_find_property(&properties, &INSTALL_NOTIFY_PROP);            if (pcsl_string_length(pproperty) > 0) {                /*                 * Remove any pending install notifications since they are only                 * retried when the suite is run.                 */                midpRemoveInstallNotification(suiteId);            }            midp_free_properties(&properties);        }        if ((status = get_suite_storage_root(suiteId, &suiteRoot)) != ALL_OK) {            break;        }        fileIteratorHandle = storage_open_file_iterator(&suiteRoot);        if (!fileIteratorHandle) {            status = IO_ERROR;            break;        }#if ENABLE_ICON_CACHE        midp_remove_suite_icons(suiteId);#endif                for (;;) {            rc = storage_get_next_file_in_iterator(&suiteRoot,                fileIteratorHandle, &filename);            if (0 != rc) {                break;            }            storage_delete_file(&pszError, &filename);            pcsl_string_free(&filename);            if (pszError != NULL) {                storageFreeError(pszError);                break;            }        }    } while (0);    pcsl_string_free(&suiteRoot);    storageCloseFileIterator(fileIteratorHandle);    (void)finish_transaction();    /*     * Notify the listeners the we've finished removing the suite.     * It should be done before remove_from_suite_list_and_save()     * call because it frees pData structure.     */    if (operationStarted) {        suite_listeners_notify(SUITESTORE_LISTENER_TYPE_REMOVE,            SUITESTORE_OPERATION_END, status, pData);    }    if (status == ALL_OK) {        (void)remove_from_suite_list_and_save(suiteId);    }    remove_storage_lock(suiteId);    return status;}/** * Moves a software package with given suite ID to the specified storage. * * @param suiteId suite ID for the installed package * @param storageId new storage ID * * @return SUITE_LOCKED if the * suite is locked, NOT_FOUND if the suite cannot be found or * invalid storage ID specified, BAD_PARAMS if attempt is made

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?