Merge pull request #5095 from koying/fixdroidappcrash
authorjmarshallnz <jcmarsha@gmail.com>
Fri, 1 Aug 2014 23:11:47 +0000 (11:11 +1200)
committerJonathan Marshall <jmarshall@xbmc.org>
Sat, 2 Aug 2014 03:59:13 +0000 (15:59 +1200)
FIX: [droid] crash if an app is favourited, then uninstalled from system
Conflicts:
xbmc/filesystem/AndroidAppDirectory.cpp

xbmc/android/activity/XBMCApp.cpp
xbmc/android/activity/XBMCApp.h
xbmc/filesystem/AndroidAppDirectory.cpp
xbmc/filesystem/AndroidAppFile.cpp

index e598df3..a9c66a9 100644 (file)
@@ -87,6 +87,9 @@ ANativeActivity *CXBMCApp::m_activity = NULL;
 ANativeWindow* CXBMCApp::m_window = NULL;
 int CXBMCApp::m_batteryLevel = 0;
 int CXBMCApp::m_initialVolume = 0;
 ANativeWindow* CXBMCApp::m_window = NULL;
 int CXBMCApp::m_batteryLevel = 0;
 int CXBMCApp::m_initialVolume = 0;
+CCriticalSection CXBMCApp::m_applicationsMutex;
+std::vector<androidPackage> CXBMCApp::m_applications;
+
 
 CXBMCApp::CXBMCApp(ANativeActivity* nativeActivity)
   : CJNIContext(nativeActivity)
 
 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);
   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()
 }
 
 void CXBMCApp::onPause()
@@ -349,22 +358,27 @@ int CXBMCApp::GetDPI()
   return dpi;
 }
 
   return dpi;
 }
 
-bool CXBMCApp::ListApplications(vector<androidPackage> *applications)
+std::vector<androidPackage> CXBMCApp::GetApplications()
 {
 {
-  CJNIList<CJNIApplicationInfo> 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<CJNIApplicationInfo> 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)
 }
 
 bool CXBMCApp::GetIconSize(const string &packageName, int *width, int *height)
index cd7d101..3218be2 100644 (file)
@@ -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 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 <androidPackage> *applications);
+  static std::vector <androidPackage> GetApplications();
   static bool GetIconSize(const std::string &packageName, int *width, int *height);
   static bool GetIcon(const std::string &packageName, void* buffer, unsigned int bufSize); 
 
   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;
   bool m_firstrun;
   bool m_exiting;
   pthread_t m_thread;
-  
+  static CCriticalSection m_applicationsMutex;
+  static std::vector<androidPackage> m_applications;
+
   static ANativeWindow* m_window;
   static CEvent m_windowCreated;
 
   static ANativeWindow* m_window;
   static CEvent m_windowCreated;
 
index 86a5409..ff7502b 100644 (file)
@@ -50,22 +50,21 @@ bool CAndroidAppDirectory::GetDirectory(const CStdString& strPath, CFileItemList
   CLog::Log(LOGDEBUG, "CAndroidAppDirectory::GetDirectory: %s",dirname.c_str()); 
   if (dirname == "apps")
   {
   CLog::Log(LOGDEBUG, "CAndroidAppDirectory::GetDirectory: %s",dirname.c_str()); 
   if (dirname == "apps")
   {
-    vector<androidPackage> applications;
-    CXBMCApp::ListApplications(&applications);
-    if (!applications.size())
+    vector<androidPackage> applications = CXBMCApp::GetApplications();
+    if (applications.empty())
     {
       CLog::Log(LOGERROR, "CAndroidAppDirectory::GetDirectory Application lookup listing failed");
       return false;
     }
     {
       CLog::Log(LOGERROR, "CAndroidAppDirectory::GetDirectory Application lookup listing failed");
       return false;
     }
-    for(unsigned int i = 0; i < applications.size(); i++)
+    for(std::vector<androidPackage>::iterator i = applications.begin(); i != applications.end(); ++i)
     {
     {
-      if (applications[i].packageName == "org.xbmc.xbmc")
+      if ((*i).packageName == "org.xbmc.xbmc")
         continue;
         continue;
-      CFileItemPtr pItem(new CFileItem(applications[i].packageName));
+      CFileItemPtr pItem(new CFileItem((*i).packageName));
       pItem->m_bIsFolder = false;
       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->SetPath(path);
-      pItem->SetLabel(applications[i].packageLabel);
+      pItem->SetLabel((*i).packageLabel);
       pItem->SetArt("thumb", path+".png");
       items.Add(pItem);
     }
       pItem->SetArt("thumb", path+".png");
       items.Add(pItem);
     }
index 3aa5a65..0c7361d 100644 (file)
@@ -45,17 +45,33 @@ CFileAndroidApp::~CFileAndroidApp(void)
 
 bool CFileAndroidApp::Open(const CURL& url)
 {
 
 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);
 
   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<androidPackage> applications = CXBMCApp::GetApplications();
+  for(std::vector<androidPackage>::iterator i = applications.begin(); i != applications.end(); ++i)
+  {
+    if ((*i).packageName == m_appname)
+      return true;
+  }
+
+  return false;
 }
 
 bool CFileAndroidApp::Exists(const CURL& url)
 {
 }
 
 bool CFileAndroidApp::Exists(const CURL& url)
 {
-  return true;
+  std::string appname =  URIUtils::GetFileName(url.Get());
+  appname = appname.substr(0, appname.size() - 4);
+
+  std::vector<androidPackage> applications = CXBMCApp::GetApplications();
+  for(std::vector<androidPackage>::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)
 }
 
 unsigned int CFileAndroidApp::Read(void* lpBuf, int64_t uiBufSize)