ApplicationDescription* ApplicationDescription::fromApplicationStatus(const ApplicationStatus& appStatus, bool isUpdating) { ApplicationDescription* appDesc = new ApplicationDescription(); appDesc->m_id = appStatus.id; appDesc->m_version = appStatus.version; appDesc->m_vendorName = appStatus.vendor; appDesc->m_vendorUrl = appStatus.vendorUrl; appDesc->m_progress = appStatus.progress; appDesc->m_appmenuName = appStatus.title; if (appStatus.state == ApplicationStatus::State_Failed) appDesc->m_status = Status_Failed; else appDesc->m_status = isUpdating ? Status_Updating : Status_Installing; LaunchPoint* defaultLP = new LaunchPoint(appDesc, appDesc->m_id, appDesc->m_id + "_default", appStatus.title, appDesc->m_appmenuName, appStatus.iconPath, "", true); defaultLP->setAsDefault(); appDesc->m_launchPoints.push_back(defaultLP); appDesc->setRemovable(true); return appDesc; }
void EmulatedCardWindow::setAppId(const std::string& id) { m_appId = id; ApplicationDescription* appDesc = ApplicationManager::instance()->getAppById(m_appId); m_statusBar->setMaximizedAppTitle(true, appDesc->launchPoints().front()->menuName().c_str()); }
void AppEffector::remove(const QString& webosAppId,const QUuid& iconUid) { WebOSApp * pWebOSapp = AppMonitor::appMonitor()->webosAppByAppId(webosAppId); if (!pWebOSapp) { qDebug() << __FUNCTION__ << ": didn't find a webos app with appId ["<<webosAppId<<"]"; return; } ApplicationDescription * pAppDesc = ApplicationManager::instance()->getAppById(StringTranslator::outputString(pWebOSapp->appId())); if (!pAppDesc) { return; } //if the app is a sysmgr builtin, then ignore if (pAppDesc->type() == ApplicationDescription::Type_SysmgrBuiltin) { return; } //check to see if the icon that triggered this is an auxiliary launch point or the main one WOAppIconType::Enum type; QString launchPointId = pWebOSapp->launchpointIdOfIcon(iconUid,&type); if (type == WOAppIconType::Auxiliary) { //yes, auxiliary...delegate to removeLaunchpoint g_message("%s: The remove was on one of the app's auxiliary icons (launchpoints)...delegating to another function to do that removal", __FUNCTION__); return removeLaunchpoint(webosAppId,launchPointId); } g_message("%s: The remove is on the app's main icon; the whole app will be removed from the system",__FUNCTION__); //else, it's the main icon, so the app removal procedure needs to take place pWebOSapp->m_stateBeingRemoved = true; //this is set in case at some point the removal process needs to go async //I'm going to hijack ApplicationManager's LS handle to make a call to remove an app json_object* payload = json_object_new_object(); LSError lserror; LSErrorInit(&lserror); ///TODO: do I want to track remove status??? json_object_object_add(payload, "id", json_object_new_string(pWebOSapp->appId().toAscii().constData())); if (!LSCall(ApplicationManager::instance()->m_serviceHandlePrivate, "palm://com.palm.appInstallService/remove",json_object_to_json_string(payload), NULL, NULL, NULL, &lserror)) { LSErrorFree(&lserror); } json_object_put(payload); //!...this HAS TO BE THE LAST CALL IN THIS FUNCTION!!! and also, make sure nothing much happens up the chain either #if defined(TARGET_DESKTOP) LauncherObject::primaryInstance()->slotAppPreRemove(*pWebOSapp,DimensionsSystemInterface::AppMonitorSignalType::AppManSourced); #endif return; }
ApplicationDescription::ApplicationDescription(const ApplicationDescription& other) : ApplicationDescriptionBase(other), mApplicationBasePath(other.basePath()), mTrustScope(other.trustScope()), mUseLuneOSStyle(other.useLuneOSStyle()), mUseWebEngine(other.useWebEngine()) { }
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; }
void DockModeWindow::setPrepareAddedToWindowManager() { m_prepareAddedToWm = true; if (G_LIKELY(s_dockGlow == 0)) { QString path(Settings::LunaSettings()->lunaSystemResourcesPath.c_str()); path.append("/dockmode/dock-loading-glow.png"); s_dockGlow = new QPixmap(path); if(s_dockGlow) s_dockGlowRefCount++; if (!s_dockGlow || s_dockGlow->isNull()) { g_critical("%s: Failed to load image '%s'", __PRETTY_FUNCTION__, qPrintable(path)); } } else { s_dockGlowRefCount++; } ApplicationDescription* appDesc = static_cast<Window*>(this)->appDescription(); int size = Settings::LunaSettings()->splashIconSize; m_icon.load(appDesc->splashIconName().c_str()); if (!m_icon.isNull()) { // scale splash icon to fit the devices screen dimensions m_icon = m_icon.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation); } else { // just use the launcher icon m_icon = appDesc->getDefaultLaunchPoint()->icon(); int newWidth = qMin((int)(m_icon.width()*1.5), size); int newHeight = qMin((int)(m_icon.height()*1.5), size); m_icon = m_icon.scaled(newWidth, newHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); } // set up the pulsing animation QPropertyAnimation* pulseIn = new QPropertyAnimation(this, "pulseOpacity"); pulseIn->setDuration(AS(cardLoadingPulseDuration)); pulseIn->setEasingCurve(AS_CURVE(cardLoadingPulseCurve)); pulseIn->setEndValue(1.0); QPropertyAnimation* pulseOut = new QPropertyAnimation(this, "pulseOpacity"); pulseOut->setDuration(AS(cardLoadingPulseDuration)); pulseOut->setEasingCurve(AS_CURVE(cardLoadingPulseCurve)); pulseOut->setEndValue(0.0); QSequentialAnimationGroup* pulseGroup = new QSequentialAnimationGroup; pulseGroup->addAnimation(pulseIn); pulseGroup->addAnimation(pulseOut); pulseGroup->setLoopCount(-1); m_pulseAnimation.addPause(AS(cardLoadingTimeBeforeShowingPulsing)); m_pulseAnimation.addAnimation(pulseGroup); m_loadingOverlayEnabled = true; m_pulseAnimation.start(); update(); }
std::string ProcessManager::launchBootTimeApp(const std::string& appDescString) { std::string processId = processIdFactory(); ApplicationDescription* desc = ApplicationDescription::fromJsonString(appDescString.c_str()); WebAppManager::instance()->onLaunchUrl(desc->entryPoint().c_str(), Window::Type_None, appDescString.c_str(), processId.c_str(), "{\"launchedAtBoot\":true}", "", ""); delete desc; return processId; }
//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; }
/** * 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::launchModal(const std::string& appDescString, const std::string& params, const std::string& launchingAppId, const std::string& launchingProcId, std::string& errMsg, int& errorCode, bool isHeadless, bool isParentPdk) { std::string processId = ""; errMsg.erase(); Window::Type winType = Window::Type_ModalChildWindowCard; if(false == isParentPdk && 0 >= launchingProcId.size()) { errorCode = SystemUiController::MissingProcessId; errMsg = "Invalid processId of the calling process"; return processId; } ApplicationDescription* desc = ApplicationDescription::fromJsonString(appDescString.c_str()); if(!desc) { errorCode = SystemUiController::InternalError; errMsg = "Error getting ApplicationDescription for the app to be launched"; return processId; } errorCode = SystemUiController::NoErr; // always create a new card if the system wants a modal card to be created, no relaunching. std::string url = desc->entryPoint(); processId = processIdFactory(); // if we want to create a headless app, the type is Window::Type_None else it Window::Type_ModalChildWindowCard if(true == isHeadless) winType = Window::Type_None; // launch the app WebAppManager::instance()->onLaunchUrlChild(url.c_str(), winType, appDescString.c_str(), processId.c_str(), params.c_str(), launchingAppId.c_str(), launchingProcId.c_str(), errorCode, isHeadless); g_debug("Launched Id %s", processId.c_str() ); delete desc; return processId; }
std::string getResourcePathFromString(const std::string& entry, const std::string& appId, const std::string& systemResourceFolder) { if (entry.empty()) return std::string(); struct stat stBuf; // Absolute path? if (entry[0] == '/') { // check if it exists and is a regular file if (::stat(entry.c_str(), &stBuf) != 0 || !S_ISREG(stBuf.st_mode)) return std::string(); return entry; } // relative path. first check in the app folder ApplicationDescription* appDesc = ApplicationManager::instance()->getAppById(appId); if (appDesc) { // First check in the locale specific folder std::string filePath = appDesc->folderPath() + "/resources/" + LocalePreferences::instance()->locale().toStdString() + "/" + entry; if (::stat(filePath.c_str(), &stBuf) == 0 && (S_ISREG(stBuf.st_mode) || S_ISLNK(stBuf.st_mode))) return filePath; // Try in the standard app folder path filePath = appDesc->folderPath() + "/" + entry; if (::stat(filePath.c_str(), &stBuf) == 0 && (S_ISREG(stBuf.st_mode) || S_ISLNK(stBuf.st_mode))) return filePath; } // Look for it in the system folder std::string filePath = systemResourceFolder + "/" + entry; if (::stat(filePath.c_str(), &stBuf) == 0 && S_ISREG(stBuf.st_mode)) return filePath; // ah well... we give up return std::string(); }
//TODO: this is a poor-man's assignment operator (operator=). Should probably be rewritten as such //TODO: won't update the icon; add that. //returns > 0 on success int ApplicationDescription::update(const ApplicationDescription& appDesc) { m_category = appDesc.m_category; m_entryPoint = appDesc.m_entryPoint; m_version = appDesc.m_version; m_folderPath = appDesc.m_folderPath; m_vendorName = appDesc.m_vendorName; m_vendorUrl = appDesc.m_vendorUrl; m_isHeadLess = appDesc.m_isHeadLess; m_hasTransparentWindows = appDesc.m_hasTransparentWindows; m_isVisible = appDesc.m_isVisible; m_appSize = appDesc.m_appSize; m_runtimeMemoryRequired = appDesc.m_runtimeMemoryRequired; m_miniIconName = appDesc.m_miniIconName; m_tapToShareSupported = appDesc.m_tapToShareSupported; m_universalSearchJsonStr = appDesc.m_universalSearchJsonStr; m_servicesJsonStr = appDesc.m_servicesJsonStr; m_accountsJsonStr = appDesc.m_accountsJsonStr; m_dockMode = appDesc.m_dockMode; m_dockModeTitle = appDesc.m_dockModeTitle; const LaunchPoint* lp = getDefaultLaunchPoint(); const LaunchPoint* nlp = appDesc.getDefaultLaunchPoint(); if ((lp) && (nlp)) { if (!nlp->iconPath().empty()) //guard a little bit...you don't know where nlp has been. { const_cast<LaunchPoint*>(lp)->updateIconPath(nlp->iconPath()); } if ((!nlp->title().empty()) && (nlp->title() != lp->title())) { const_cast<LaunchPoint*>(lp)->updateTitle(nlp->title()); } } //WARNING...doesn't propagate changes automatically to launcher, or things that are holding a ref to this... // currently this is done in the callers of update() // TODO: update m_keywords // TODO: update defaultLP->title return 1; }
//TODO: CHANGEME!!! This way of getting info is deprecated, as the JS component of com.palm.launcher that did the work is no longer existing // in Dfish and onward. void AppEffector::info(ExternalApp * pApp) { //TODO: IMPLEMENT (unfinished) if (!pApp) { return; } //TODO: TEMP: only handle WebOS apps for the moment WebOSApp * pWoApp = qobject_cast<WebOSApp *>(pApp); if (!pWoApp) { return; } ApplicationDescription * pAppDesc = ApplicationManager::instance()->getAppById(StringTranslator::outputString(pWoApp->appId())); if (!pAppDesc) { //qDebug() << "ApplicationDescription for " << pWoApp->appId() << " not found in the AppMan"; return; } //see if the app is actually a built-in if (pAppDesc->type() == ApplicationDescription::Type_SysmgrBuiltin) { //TODO: no info for these...handle it better by giving the user something, but for now since the javascript part that gives the // info probably will go all weird on a sysmgr builtin, don't try it right now return; } //get the primary launchpoint, because that's what the app info command wants const LaunchPoint * pLp = pAppDesc->getDefaultLaunchPoint(); if (!pLp) { //there isn't one? hmm ok. return; } std::string launcherAppId = std::string("com.palm.launcher"); std::string launcherProcessId = std::string("launcher-0"); std::string procId = std::string(""); std::string errMsg = std::string(""); //TODO: don't form the json manually std::string request = std::string("{\"action\":\"showAppInfo\", \"appInfo\":\"") + pLp->launchPointId() + std::string("\"}"); if (procId.empty()) { //normal launch procId = WebAppMgrProxy::instance()->appLaunch( launcherAppId, request, launcherAppId, launcherProcessId, errMsg); } if (procId.empty()) { //qDebug() << "Failed to launch " << pWoApp->appId() << ": " << StringTranslator::inputString(errMsg); } else { //qDebug() << "Request to launch " << pWoApp->appId() << " " << StringTranslator::inputString(request); } }
/** * 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; }
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; }
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); } }
void AppEffector::launch(ExternalApp * pApp,const QUuid& optionalIconUid) { if (!pApp) { return; } //TODO: TEMP: only handle WebOS apps for the moment WebOSApp * pWoApp = qobject_cast<WebOSApp *>(pApp); if (!pWoApp) { return; } ApplicationDescription * pAppDesc = ApplicationManager::instance()->getAppById(StringTranslator::outputString(pWoApp->appId())); if (!pAppDesc) { //check to see if it is a pending application pAppDesc = ApplicationManager::instance()->getPendingAppById(StringTranslator::outputString(pWoApp->appId())); if (!pAppDesc) { g_message("%s: error: It's hopeless; app id [%s] that was being launched by the launcher has no mapping in application manager (neither as an installed app nor a pending app. Aborting launch attempt.", __FUNCTION__,qPrintable(pWoApp->appId())); return; } } //check and see if this is some auxiliary launch point of the app //virtual QString launchpointIdOfIcon(const QUuid& iconUid,WOAppIconType::Enum * p_r_type = 0) const; WOAppIconType::Enum type; QString launchPointId = pWoApp->launchpointIdOfIcon(optionalIconUid,&type); std::string launcherAppId = std::string("com.palm.launcher"); std::string launcherProcessId = std::string("launcher-0"); std::string procId = std::string(""); std::string errMsg = std::string(""); std::string request = pAppDesc->getDefaultLaunchPoint()->params(); if (type == WOAppIconType::Auxiliary) { //retrieve the launch point const LaunchPoint * pLaunchPoint = pAppDesc->findLaunchPoint(StringTranslator::outputString(launchPointId)); if (pLaunchPoint) { request = pLaunchPoint->params(); } } //see if the app is actually a built-in if (pAppDesc->type() == ApplicationDescription::Type_SysmgrBuiltin) { ///launch direct pAppDesc->startSysmgrBuiltIn(); // //fake a procId procId = "SYSMGR_BUILTIN"; } else if (procId.empty()) { //normal launch procId = WebAppMgrProxy::instance()->appLaunch( StringTranslator::outputString(pWoApp->appId()), request, launcherAppId, launcherProcessId, errMsg); } if (procId.empty()) { qDebug() << "Failed to launch " << pWoApp->appId() << ": " << StringTranslator::inputString(errMsg); } else { qDebug() << "Request to launch " << pWoApp->appId() << " " << StringTranslator::inputString(request); } }