From: jmarshallnz Date: Fri, 1 Aug 2014 23:11:47 +0000 (+1200) Subject: Merge pull request #5095 from koying/fixdroidappcrash X-Git-Tag: 13.2b3-Gotham~3 X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_xbmc;a=commitdiff_plain;h=2d2eff9c723670fd76f711e94bad69fbd587438c Merge pull request #5095 from koying/fixdroidappcrash FIX: [droid] crash if an app is favourited, then uninstalled from system Conflicts: xbmc/filesystem/AndroidAppDirectory.cpp --- diff --git a/xbmc/android/activity/XBMCApp.cpp b/xbmc/android/activity/XBMCApp.cpp index e598df3..a9c66a9 100644 --- a/xbmc/android/activity/XBMCApp.cpp +++ b/xbmc/android/activity/XBMCApp.cpp @@ -87,6 +87,9 @@ ANativeActivity *CXBMCApp::m_activity = NULL; ANativeWindow* CXBMCApp::m_window = NULL; int CXBMCApp::m_batteryLevel = 0; int CXBMCApp::m_initialVolume = 0; +CCriticalSection CXBMCApp::m_applicationsMutex; +std::vector CXBMCApp::m_applications; + CXBMCApp::CXBMCApp(ANativeActivity* nativeActivity) : CJNIContext(nativeActivity) @@ -129,6 +132,12 @@ void CXBMCApp::onResume() CJNIIntentFilter batteryFilter; batteryFilter.addAction("android.intent.action.BATTERY_CHANGED"); registerReceiver(*this, batteryFilter); + + // Clear the applications cache. We could have installed/deinstalled apps + { + CSingleLock lock(m_applicationsMutex); + m_applications.clear(); + } } void CXBMCApp::onPause() @@ -349,22 +358,27 @@ int CXBMCApp::GetDPI() return dpi; } -bool CXBMCApp::ListApplications(vector *applications) +std::vector CXBMCApp::GetApplications() { - CJNIList packageList = GetPackageManager().getInstalledApplications(CJNIPackageManager::GET_ACTIVITIES); - int numPackages = packageList.size(); - for (int i = 0; i < numPackages; i++) + CSingleLock lock(m_applicationsMutex); + if (m_applications.empty()) { - androidPackage newPackage; - newPackage.packageName = packageList.get(i).packageName; - newPackage.packageLabel = GetPackageManager().getApplicationLabel(packageList.get(i)).toString(); - CJNIIntent intent = GetPackageManager().getLaunchIntentForPackage(newPackage.packageName); - if (!intent || !intent.hasCategory("android.intent.category.LAUNCHER")) - continue; - - applications->push_back(newPackage); + CJNIList packageList = GetPackageManager().getInstalledApplications(CJNIPackageManager::GET_ACTIVITIES); + int numPackages = packageList.size(); + for (int i = 0; i < numPackages; i++) + { + androidPackage newPackage; + newPackage.packageName = packageList.get(i).packageName; + newPackage.packageLabel = GetPackageManager().getApplicationLabel(packageList.get(i)).toString(); + CJNIIntent intent = GetPackageManager().getLaunchIntentForPackage(newPackage.packageName); + if (!intent || !intent.hasCategory("android.intent.category.LAUNCHER")) + continue; + + m_applications.push_back(newPackage); + } } - return true; + + return m_applications; } bool CXBMCApp::GetIconSize(const string &packageName, int *width, int *height) diff --git a/xbmc/android/activity/XBMCApp.h b/xbmc/android/activity/XBMCApp.h index cd7d101..3218be2 100644 --- a/xbmc/android/activity/XBMCApp.h +++ b/xbmc/android/activity/XBMCApp.h @@ -86,7 +86,7 @@ public: static int GetBatteryLevel(); static bool StartActivity(const std::string &package, const std::string &intent = std::string(), const std::string &dataType = std::string(), const std::string &dataURI = std::string()); - static bool ListApplications(std::vector *applications); + static std::vector GetApplications(); static bool GetIconSize(const std::string &packageName, int *width, int *height); static bool GetIcon(const std::string &packageName, void* buffer, unsigned int bufSize); @@ -124,7 +124,9 @@ private: bool m_firstrun; bool m_exiting; pthread_t m_thread; - + static CCriticalSection m_applicationsMutex; + static std::vector m_applications; + static ANativeWindow* m_window; static CEvent m_windowCreated; diff --git a/xbmc/filesystem/AndroidAppDirectory.cpp b/xbmc/filesystem/AndroidAppDirectory.cpp index 86a5409..ff7502b 100644 --- a/xbmc/filesystem/AndroidAppDirectory.cpp +++ b/xbmc/filesystem/AndroidAppDirectory.cpp @@ -50,22 +50,21 @@ bool CAndroidAppDirectory::GetDirectory(const CStdString& strPath, CFileItemList CLog::Log(LOGDEBUG, "CAndroidAppDirectory::GetDirectory: %s",dirname.c_str()); if (dirname == "apps") { - vector applications; - CXBMCApp::ListApplications(&applications); - if (!applications.size()) + vector applications = CXBMCApp::GetApplications(); + if (applications.empty()) { CLog::Log(LOGERROR, "CAndroidAppDirectory::GetDirectory Application lookup listing failed"); return false; } - for(unsigned int i = 0; i < applications.size(); i++) + for(std::vector::iterator i = applications.begin(); i != applications.end(); ++i) { - if (applications[i].packageName == "org.xbmc.xbmc") + if ((*i).packageName == "org.xbmc.xbmc") continue; - CFileItemPtr pItem(new CFileItem(applications[i].packageName)); + CFileItemPtr pItem(new CFileItem((*i).packageName)); pItem->m_bIsFolder = false; - CStdString path = StringUtils::Format("androidapp://%s/%s/%s", url.GetHostName().c_str(), dirname.c_str(), applications[i].packageName.c_str()); + std::string path = StringUtils::Format("androidapp://%s/%s/%s", url.GetHostName().c_str(), dirname.c_str(), (*i).packageName.c_str()); pItem->SetPath(path); - pItem->SetLabel(applications[i].packageLabel); + pItem->SetLabel((*i).packageLabel); pItem->SetArt("thumb", path+".png"); items.Add(pItem); } diff --git a/xbmc/filesystem/AndroidAppFile.cpp b/xbmc/filesystem/AndroidAppFile.cpp index 3aa5a65..0c7361d 100644 --- a/xbmc/filesystem/AndroidAppFile.cpp +++ b/xbmc/filesystem/AndroidAppFile.cpp @@ -45,17 +45,33 @@ CFileAndroidApp::~CFileAndroidApp(void) bool CFileAndroidApp::Open(const CURL& url) { - m_url = url; m_appname = URIUtils::GetFileName(url.Get()); m_appname = m_appname.substr(0, m_appname.size() - 4); - return m_appname.size() > 0; + std::vector applications = CXBMCApp::GetApplications(); + for(std::vector::iterator i = applications.begin(); i != applications.end(); ++i) + { + if ((*i).packageName == m_appname) + return true; + } + + return false; } bool CFileAndroidApp::Exists(const CURL& url) { - return true; + std::string appname = URIUtils::GetFileName(url.Get()); + appname = appname.substr(0, appname.size() - 4); + + std::vector applications = CXBMCApp::GetApplications(); + for(std::vector::iterator i = applications.begin(); i != applications.end(); ++i) + { + if ((*i).packageName == appname) + return true; + } + + return false; } unsigned int CFileAndroidApp::Read(void* lpBuf, int64_t uiBufSize)