//TODO: this should eventually just be the == operator. However, for now, allow operator== to be a weaker comparison
//whereas this function will compare every *info* field (not counting internal fields like execution lock, etc)
bool ApplicationDescription::strictCompare(const ApplicationDescription& cmp) const {

    if (m_id != cmp.id())
        return false;
    if (m_category != cmp.m_category)
        return false;
    if (m_entryPoint != cmp.m_entryPoint)
        return false;
    if (cmp.m_isRemovable && (m_version != cmp.m_version))
        return false;
    if (m_mimeTypes !=  cmp.m_mimeTypes)
        return false;
    if (m_redirectTypes != cmp.m_redirectTypes)
        return false;
    if (m_folderPath !=  cmp.m_folderPath)
        return false;
    if (m_vendorName != cmp.m_vendorName)
        return false;
    if (m_vendorUrl != cmp.m_vendorUrl)
        return false;
    if (m_isHeadLess != cmp.m_isHeadLess)
        return false;
    if (m_hasTransparentWindows != cmp.m_hasTransparentWindows)
        return false;
    if (m_isVisible != cmp.m_isVisible)
        return false;
    if (m_appSize != cmp.m_appSize)
        return false;
    if (m_tapToShareSupported != cmp.m_tapToShareSupported)
        return false;

    return true;
}
Ejemplo n.º 2
0
bool WebAppManager::validateApplication(const ApplicationDescription& desc)
{
    if (desc.id().length() == 0)
        return false;

    if (desc.entryPoint().isLocalFile() && !QFile::exists(desc.entryPoint().toLocalFile()))
        return false;

    return true;
}
bool ApplicationDescription::operator!=(const ApplicationDescription& cmp) const {
    return (m_id != cmp.id());
}
ApplicationDescription* ApplicationDescription::fromFile(const std::string& filePath, const std::string& folderPath)
{
    bool success = false;
    ApplicationDescription* appDesc = 0;
    char* jsonStr = 0;
    const gchar* palmAppDirPrefix = "/usr/palm/applications/";
    std::vector<MimeRegInfo> extractedMimeTypes;
    std::string launchParams;

    std::string builtinEntrypt;
    std::string builtinArgs;

    jsonStr = readFile(filePath.c_str());
    if (!jsonStr || !g_utf8_validate(jsonStr, -1, NULL))
    {
        return 0;
    }

    struct json_object* root=0;
    struct json_object* label=0;

    std::string title, icon, dirPath;
    gchar* dirPathCStr;

    dirPathCStr = g_path_get_dirname(filePath.c_str());
    dirPath = dirPathCStr;
    dirPath += "/";
    g_free(dirPathCStr);

    root = json_tokener_parse( jsonStr );
    if( !root || is_error( root ) )
    {
        g_warning("%s: Failed to parse '%s' into a JSON string", __FUNCTION__, filePath.c_str() );
        goto Done;
    }

    appDesc = new ApplicationDescription();

    appDesc->m_folderPath = folderPath;

    // ID: mandatory
    label = json_object_object_get(root, "id");
    if( label && !is_error(label) )
    {
        appDesc->m_id = json_object_get_string(label);
    }
    else
    {
        g_warning("%s: App %s does not have an ID", __FUNCTION__, filePath.c_str() );
        goto Done;
    }


    // MAIN: optional
    label = json_object_object_get(root, "main");
    if( label && !is_error(label) )
    {
        appDesc->m_entryPoint = json_object_get_string(label);
    }
    else
    {
        appDesc->m_entryPoint = "index.html";
    }

    if (!strstr(appDesc->m_entryPoint.c_str(), "://"))
        appDesc->m_entryPoint = std::string("file://") + dirPath + appDesc->m_entryPoint;


    // TITLE: mandatory
    label = json_object_object_get(root, "title");
    if( label && !is_error(label) )
    {
        appDesc->m_title = json_object_get_string(label);
    }
    else
    {
        g_warning("%s: App %s does not have a title",__FUNCTION__, filePath.c_str() );
        goto Done;
    }

    // SHORT NAME: optional
    label = json_object_object_get(root,"appmenu");
    if ( label && !is_error(label))
    {
        appDesc->m_appmenuName = json_object_get_string(label);
    }
    else
        appDesc->m_appmenuName = appDesc->m_title;

    // KEYWORDS: optional
    label = json_object_object_get(root,"keywords");
    if ( label && !is_error(label)) {
        appDesc->m_keywords.addKeywords(label);
    }

    //MIME HANDLING REGISTRATIONS: optional
    label = json_object_object_get(root,"mimeTypes");
    if ( label && !is_error(label)) {
        if (utilExtractMimeTypes(label,extractedMimeTypes)) {
            //found some!
            for (std::vector<MimeRegInfo>::iterator it = extractedMimeTypes.begin();
                    it != extractedMimeTypes.end();
                    ++it)
            {
                if ((*it).mimeType.size()) {
                    // ADD BY MIME TYPE.  The extension that is appropriate for this mimeType will be automatically filled in into "extension" if successful
                    if (MimeSystem::instance()->addResourceHandler((*it).extension,(*it).mimeType,!((*it).stream),appDesc->id(),NULL,false) > 0)
                        appDesc->m_mimeTypes.push_back(ResourceHandler((*it).extension,(*it).mimeType,appDesc->id(),(*it).stream));			//success adding to mime system, so add it to this app descriptor for bookeeping purposes
                }
                else if ((*it).extension.size()) {
                    // ADD BY EXTENSION... count on the extension->mime mapping to already exist, or this will fail
                    if (MimeSystem::instance()->addResourceHandler((*it).extension,!((*it).stream),appDesc->id(),NULL,false) > 0) {
                        //get the mime type
                        MimeSystem::instance()->getMimeTypeByExtension((*it).extension,(*it).mimeType);
                        appDesc->m_mimeTypes.push_back(ResourceHandler((*it).extension,(*it).mimeType,appDesc->id(),(*it).stream));
                    }
                }
                else if ((*it).scheme.size()) {			//TODO: fix this so it's more robust; it should check if the way the appinfo file specified the scheme is in fact a valid "scheme form" regexp and if not, make it one
                    // ADD REDIRECT: THIS IS A SCHEME or "COMMAND" FORM.... (e.g. "tel://")
                    (*it).scheme = std::string("^")+(*it).scheme+std::string(":");
                    if (MimeSystem::instance()->addRedirectHandler((*it).scheme,appDesc->id(),NULL,true,false) > 0) {
                        appDesc->m_redirectTypes.push_back(RedirectHandler((*it).scheme,appDesc->id(),true));
                    }
                }
                else if ((*it).urlPattern.size()) {
                    // ADD REDIRECT: THIS IS A PURE REDIRECT FORM... (e.g. "^[^:]+://www.youtube.com/watch\\?v="
                    if (MimeSystem::instance()->addRedirectHandler((*it).urlPattern,appDesc->id(),NULL,false,false) > 0) {
                        appDesc->m_redirectTypes.push_back(RedirectHandler((*it).urlPattern,appDesc->id(),false));
                    }
                }
            }
        }
    }

    // ICON: we have a default if this is not present.
    label = json_object_object_get(root, "icon");
    if( label && !is_error(label) )
    {
        icon = dirPath + json_object_get_string(label);
    }
    else
        icon = dirPath + "icon.png";

    // Optional parameters
    success = true;

    // Type: optional (defaults to Type_Web)
    label = json_object_object_get(root, "type");
    if (label && !is_error(label) && json_object_is_type(label, json_type_string)) {
        if (strncmp(json_object_get_string(label), "game", 4) == 0)
            appDesc->m_type = Type_Native;
        else if (strncmp(json_object_get_string(label), "pdk", 3) == 0)
            appDesc->m_type = Type_PDK;
        else if (strncmp(json_object_get_string(label), "qt", 2) == 0)
            appDesc->m_type = Type_Qt;
        else if (strncmp(json_object_get_string(label), "sysmgrbuiltin" , 13 ) == 0)
            appDesc->m_type = Type_SysmgrBuiltin;
        else
            appDesc->m_type = Type_Web;
    }

    // SPLASH ICON: optional (Used for loading/splash screen for cards)
    label = json_object_object_get(root, "splashicon");
    if (label && !is_error(label)) {
        appDesc->m_splashIconName = dirPath + json_object_get_string(label);
    }
    // SPLASH BACKGROUND: optional (Used for loading/splash screen for cards)
    label = json_object_object_get(root, "splashBackground");
    if (label && !is_error(label) && json_object_is_type(label, json_type_string)) {
        appDesc->m_splashBackgroundName = dirPath + json_object_get_string(label);
    }
    else {
        label = json_object_object_get(root, "splashbackground");
        if (label && !is_error(label) && json_object_is_type(label, json_type_string)) {
            appDesc->m_splashBackgroundName = dirPath + json_object_get_string(label);
        }
    }

    // MINI ICON: optional (Used for notification banner area)
    label = json_object_object_get(root, "miniicon");
    if( label && !is_error(label) )
    {
        appDesc->m_miniIconName = json_object_get_string(label);
    }
    else
        appDesc->m_miniIconName = "miniicon.png";

    appDesc->m_miniIconName = dirPath + appDesc->m_miniIconName;

    // LAUNCH IN NEW GROUP: optional (Used to prevent app from launching in current card stack)
    label = json_object_object_get(root, "launchinnewgroup");
    if( label && !is_error(label) )
    {
        appDesc->m_launchInNewGroup = json_object_get_boolean(label);
    }
    else
        appDesc->m_launchInNewGroup = false;

    // CATEGORY: optional
    label = json_object_object_get(root, "category");
    if( label && !is_error(label) )
    {
        appDesc->m_category = json_object_get_string(label);
    }

    // VENDOR: optional
    label = json_object_object_get(root, "vendor");
    if( label && !is_error(label) )
    {
        appDesc->m_vendorName = json_object_get_string(label);
    }
    else if (g_str_has_prefix(dirPath.c_str(), palmAppDirPrefix)) {
        appDesc->m_vendorName = "Palm, Inc.";
    }

    // VENDOR URL: optional
    label = json_object_object_get(root, "vendorurl");
    if( label && !is_error(label) )
    {
        appDesc->m_vendorUrl = json_object_get_string(label);
    }

    // SIZE: optional
    label = json_object_object_get(root, "appsize");
    if( label && !is_error(label) )
    {
        appDesc->m_appSize = (unsigned int) json_object_get_int(label);
    }

    // RUNTIME MEMORY REQUIRED: optional
    label = json_object_object_get(root, "requiredMemory");
    if( label && !is_error(label) )
    {
        appDesc->m_runtimeMemoryRequired = (unsigned int) json_object_get_int(label);
        //json_object_put( label );
    }

    // HEADLESS: optional
    label = json_object_object_get(root, "noWindow");
    if( label && !is_error(label) )
    {
        appDesc->m_isHeadLess = (strcasecmp( json_object_get_string(label), "true") == 0);
    }

    //VISIBLE: optional* by default the launch icons are visible...set to false in the json and they won't show in the
    //launcher screen
    label = json_object_object_get(root, "visible");
    if( label && !is_error(label) )
    {
        if (json_object_is_type(label,json_type_string))
            appDesc->m_isVisible = (strcasecmp( json_object_get_string(label), "true") == 0);
        else
            appDesc->m_isVisible = json_object_get_boolean(label);
    }

    // TRANSPARENT: optional
    label = json_object_object_get(root, "transparent");
    if( label && !is_error(label) )
    {
        appDesc->m_hasTransparentWindows = (strcasecmp( json_object_get_string(label), "true") == 0);
    }

    // VERSION: optional?
    label = json_object_object_get(root, "version");
    if (label && !is_error(label)) {
        appDesc->m_version = json_object_get_string(label);
    }

    // additional attributes, like http proxy
    label = json_object_object_get(root, "attributes");
    if (label && !is_error(label)) {
        appDesc->m_attributes = json_object_get_string(label);
    }

    // REMOVABLE: optional
    label = json_object_object_get(root, "removable");
    if (label && !is_error(label) && json_object_is_type(label, json_type_boolean)) {
        // Any appinfo.json can set removable to true. But if you want to set removable to false you better be a trusted palm application
        // NOTE: we should always be able to trust the removable flag set in the appinfo
        appDesc->m_isRemovable = json_object_get_boolean(label);
        g_debug("%s: App %s is %s because of appinfo.json",__FUNCTION__, appDesc->m_id.c_str(), appDesc->m_isRemovable ? "removable" : "non-removable");
    }
    else {
        // apps in ROM are never removable
        appDesc->m_isRemovable = !(folderPath.find("/usr") == 0);
        g_debug("%s: App %s is %s by default",__FUNCTION__, appDesc->m_id.c_str(), appDesc->m_isRemovable ? "removable" : "non-removable");
    }

    // DOCK ENABLED: optional (defines if this app can provide a Dock mode stage)
    label = json_object_object_get(root, "exhibitionMode");
    if (!label || is_error (label)) // maintaining backward compatibility
        label = json_object_object_get(root, "dockMode");

    if (label && !is_error(label) && json_object_is_type(label, json_type_boolean))
    {
        appDesc->m_dockMode = json_object_get_boolean(label);
        if(appDesc->m_dockMode) {
            // read the optional Dock mode parameters
            struct json_object *dockOptions=0, *dockLabel=0;

            // DOCK Mode options: (optional)
            dockOptions = json_object_object_get(root, "exhibitionModeOptions");
            if (!dockOptions || is_error (dockOptions)) // maintaining backward compatibility
                dockOptions = json_object_object_get(root, "dockModeOptions");

            if (dockOptions && !is_error(dockOptions)) {
                dockLabel = json_object_object_get(dockOptions, "title");
                if (dockLabel && !is_error(dockLabel) && json_object_is_type(dockLabel, json_type_string)) {
                    appDesc->m_dockModeTitle = json_object_get_string(dockLabel);
                }
                else {
                    appDesc->m_dockModeTitle = appDesc->m_appmenuName;
                }
            }
            else {
                appDesc->m_dockModeTitle = appDesc->m_appmenuName;
            }
        }
    }

    // Hardware features needed: optional
    label = json_object_object_get(root, "hardwareFeaturesNeeded");
    if (label && !is_error(label) && json_object_is_type(label, json_type_array)) {

        for (int i = 0; i < json_object_array_length(label); i++) {

            struct json_object* entry = json_object_array_get_idx(label, i);
            if (!entry  || is_error(entry))
                continue;

            if (!json_object_is_type(entry, json_type_string))
                continue;

            const char* str = json_object_get_string(entry);

            if (strncasecmp(str, "wifi", 4) == 0)
                appDesc->m_hardwareFeaturesNeeded |= HardwareFeaturesNeeded_Wifi;
            else if (strncasecmp(str, "bluetooth", 9) == 0)
                appDesc->m_hardwareFeaturesNeeded |= HardwareFeaturesNeeded_Bluetooth;
            else if (strncasecmp(str, "compass", 7) == 0)
                appDesc->m_hardwareFeaturesNeeded |= HardwareFeaturesNeeded_Compass;
            else if (strncasecmp(str, "accelerometer", 13) == 0)
                appDesc->m_hardwareFeaturesNeeded |= HardwareFeaturesNeeded_Accelerometer;
        }
    }

    //Universal Search JSON objct: optional
    label = json_object_object_get(root, "universalSearch");
    if(label && !is_error(label)) {
        appDesc->m_universalSearchJsonStr = json_object_to_json_string(label);
    }

    // Services JSON array: optional
    label = json_object_object_get(root, "services");
    if (label && !is_error(label))
        appDesc->m_servicesJsonStr = json_object_to_json_string(label);

    // Accounts JSON array: optional
    label = json_object_object_get(root, "accounts");
    if (label && !is_error(label))
        appDesc->m_accountsJsonStr = json_object_to_json_string(label);

    // Launch params: optional
    label = json_object_object_get(root, "params");
    if (label && !is_error(label)) {
        if (appDesc->m_type == Type_Qt)
            launchParams = json_object_get_string(label);
        else
            launchParams = json_object_to_json_string(label);
    }

    // Tap to Share Supported: optional
    label = json_object_object_get(root, "tapToShareSupported");
    if (label && !is_error(label)) {
        appDesc->m_tapToShareSupported = json_object_get_boolean(label);
    }

    // Requested Window Orientation: optional
    label = json_object_object_get(root, "requestedWindowOrientation");
    if( label && !is_error(label) && json_object_is_type(label, json_type_string))
    {
        appDesc->m_requestedWindowOrientation = json_object_get_string(label);
    }


    //check to see if it's a sysmgr-builtin
    if (appDesc->m_type == Type_SysmgrBuiltin)
    {
        //must have an entrypoint
        label = json_object_object_get(root,"entrypoint");
        if ((!label) || is_error(label))
        {
            g_warning("%s: App %s of type SysmgrBuiltin doesn't name an entrypoint",__FUNCTION__,appDesc->m_id.c_str());
            success = false;
            goto Done;
        }
        builtinEntrypt = json_object_get_string(label);
        label = json_object_object_get(root,"args");
        if (label && !is_error(label))
            builtinArgs = json_object_get_string(label);
        else
            builtinArgs = "";

        //update fields that can be localized   ...won't be done automatically because of sysmgr builtins being in a special location
        appDesc->updateSysmgrBuiltinWithLocalization();

        //try and create a launch helper
        if (appDesc->initSysmgrBuiltIn(ApplicationManager::instance(),builtinEntrypt,builtinArgs) == false)
        {
            //failed...something was specified wrong
            g_warning("%s: App %s cannot be formed into a sysmgrbuiltin: entry = [%s] , args = [%s]",
                      __FUNCTION__,appDesc->m_id.c_str(),builtinEntrypt.c_str(),builtinArgs.c_str());
            success = false;
            goto Done;
        }
    }
Done:

    if( root && !is_error(root) )json_object_put(root);

    delete [] jsonStr;

    if (!success) {
        delete appDesc;
        return 0;
    }

    // Default launchpoint (with empty params)
    LaunchPoint * defaultLp = new LaunchPoint(appDesc,
            appDesc->m_id,
            appDesc->m_id + "_default",
            appDesc->m_title, appDesc->m_appmenuName, icon, launchParams,appDesc->m_isRemovable);
    defaultLp->setAsDefault();
    appDesc->m_launchPoints.push_back(defaultLp);

    return appDesc;
}
Ejemplo n.º 5
0
void WebAppBase::attach(WebPage* page)
{
	WebAppManager::instance()->reportAppLaunched(page->appId(),
												 page->processId());
	
	if (m_page) {
		detach();
	}

	m_page = page;
	m_page->setClient(this);

	m_appId = page->appId();
	m_processId = page->processId();

	createActivity();

	ApplicationDescription* appDesc = getAppDescription();
	if (appDesc == NULL || appDesc->id().empty() || appDesc->attributes().empty()) {
	    return;
	}

	struct json_object* root = json_tokener_parse(appDesc->attributes().c_str());

	if (!root || is_error(root))
	{
	    fprintf(stderr, "Failed to parse '%s' into a JSON string.\n",
	            appDesc->attributes().c_str());
	    return;
	}

	// parse out optional http proxy host and port app attributes
    char* httpProxyHost = NULL;
    int   httpProxyPort = 0;

    struct json_object* label = json_object_object_get(root, "proxyhost");
	if (label && !is_error(label)) {
	    httpProxyHost = json_object_get_string(label);
	}

	label = json_object_object_get(root, "proxyport");
	if (label && !is_error(label)) {
	    httpProxyPort = json_object_get_int(label);
	}

	if (httpProxyHost != NULL && httpProxyPort != 0 && m_page->webkitPage()) {
	    m_page->webkitPage()->enableHttpProxy(httpProxyHost, httpProxyPort);
	}

	// parse out optional data connection interface type attributes
    char* interfaceName = NULL;

    label = json_object_object_get(root, "forceInterface");
	if (label && !is_error(label)) {
		interfaceName = json_object_get_string(label);
	}

	if (interfaceName != NULL && m_page->webkitPage()) {
		if (0 == strcmp(interfaceName, wanIdentifierString)) {
			m_page->webkitPage()->forceNetworkInterface(Settings::LunaSettings()->wanInterfaceName.c_str());  // use cellular
		} else if (0 == strcmp(interfaceName, wifiIdentifierString)) {
			m_page->webkitPage()->forceNetworkInterface(Settings::LunaSettings()->wifiInterfaceName.c_str()); // use wifi
		} else {
			m_page->webkitPage()->forceNetworkInterface(NULL); // use any
		}
	}

	if (root && !is_error(root)) {
        json_object_put(root);
    }
}
Ejemplo n.º 6
0
/**
 * Launch an application (webApps only, not native).
 *
 * @param appId The application ID to launch.
 * @param params The call parameters.
 * @param the ID of the application performing the launch (can be NULL).
 * @param launchingProcId (can be NULL).
 * @param errMsg The error message (will be empty if this call was successful).
 *
 * @todo: this should now be moved private and be protected...leaving it for now as to not break stuff and make things
 * slightly faster for intra-sysmgr mainloop launches
 *
 * @return The process ID of the newly launched application. Empty upon error. If empty lool at errMsg.
 */
std::string ProcessManager::launch(const std::string& appDescString, const std::string& params, 
		const std::string& launchingAppId, const std::string& launchingProcId, std::string& errMsg)
{
	std::string processId = "";
	ApplicationDescription* desc = ApplicationDescription::fromJsonString(appDescString.c_str());
	errMsg.erase();

	// This now will only launch Web Apps. Native Apps are now launched by the WebAppMgrProxy.

	// Find out what type of window we need to create
	Window::Type winType = Window::Type_Card;
	std::string winTypeStr;
	if (extractFromJson(params, "windowType", winTypeStr)) {

		if (winTypeStr == "dashboard")
			winType = Window::Type_Dashboard;
		else if (winTypeStr == "popupalert")
			winType = Window::Type_PopupAlert;
		else if (winTypeStr == "emergency")
			winType = Window::Type_Emergency;
		else if (winTypeStr == "dockModeWindow") // $$$ FIX THIS, it is just a patch to test Dock mode apps for now
			winType = Window::Type_DockModeWindow;
		else {
			winType = Window::Type_Emulated_Card;

			if (desc->uiRevision() == 2) {
				winType = Window::Type_Card;
			}
		}
	}
	
	if (winType == Window::Type_Card) {
		if (desc->uiRevision() != 2) {
			winType = Window::Type_Emulated_Card;
		}

	}
		
	// Get a list of all apps
	typedef std::list<const ProcessBase*> ProcessList;	
	ProcessList runningApps = WebAppManager::instance()->runningApps();
	const ProcessBase* app = 0;
	
	for (ProcessList::const_iterator it = runningApps.begin(); it != runningApps.end(); ++it) {
		if ((*it)->appId() == desc->id()) {
			app = (*it);
			processId = app->processId();
			break;
		}
	}
	
	if (!app) {

		// App not running? Launch it

		std::string url = desc->entryPoint();

		if (desc->isHeadLess())
			winType = Window::Type_None;

		processId = processIdFactory();

		WebAppManager::instance()->onLaunchUrl(url.c_str(),
											   winType,
											   appDescString.c_str(),
											   processId.c_str(),
											   params.c_str(), launchingAppId.c_str(), launchingProcId.c_str());
		g_debug("Launched Id %s", processId.c_str() );
	}
	else {
		WebAppManager::instance()->onRelaunchApp(processId.c_str(), params.c_str(), launchingAppId.c_str(), launchingProcId.c_str());
	}
	
	delete desc;
	
	return processId;
}