Merge pull request #4875 from koying/fixdroidremotekeyboard
[vuplus_xbmc] / xbmc / addons / GUIDialogAddonInfo.cpp
index a17d23b..f393ebe 100644 (file)
 #include "utils/FileOperationJob.h"
 #include "utils/StringUtils.h"
 #include "utils/URIUtils.h"
+#include "utils/log.h"
 #include "addons/AddonInstaller.h"
 #include "pvr/PVRManager.h"
+#include "Util.h"
 
 #define CONTROL_BTN_INSTALL          6
 #define CONTROL_BTN_ENABLE           7
@@ -87,7 +89,7 @@ bool CGUIDialogAddonInfo::OnMessage(CGUIMessage& message)
           OnInstall();
           return true;
         }
-        else if (CGUIDialogYesNo::ShowAndGetInput(24037, 750, 0, 0))
+        else
         {
           OnUninstall();
           return true;
@@ -143,7 +145,7 @@ void CGUIDialogAddonInfo::UpdateControls()
 {
   CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc/addons");
   bool isInstalled = NULL != m_localAddon.get();
-  bool isSystem = isInstalled && m_localAddon->Path().Left(xbmcPath.size()).Equals(xbmcPath);
+  bool isSystem = isInstalled && StringUtils::StartsWith(m_localAddon->Path(), xbmcPath);
   bool isEnabled = isInstalled && m_item->GetProperty("Addon.Enabled").asBoolean();
   bool isUpdatable = isInstalled && m_item->GetProperty("Addon.UpdateAvail").asBoolean();
   if (isInstalled)
@@ -169,8 +171,7 @@ void CGUIDialogAddonInfo::UpdateControls()
 
 void CGUIDialogAddonInfo::OnUpdate()
 {
-  CStdString referer;
-  referer.Format("Referer=%s-%s.zip",m_localAddon->ID().c_str(),m_localAddon->Version().c_str());
+  CStdString referer = StringUtils::Format("Referer=%s-%s.zip",m_localAddon->ID().c_str(),m_localAddon->Version().c_str());
   CAddonInstaller::Get().Install(m_addon->ID(), true, referer); // force install
   Close();
 }
@@ -181,30 +182,47 @@ void CGUIDialogAddonInfo::OnInstall()
   Close();
 }
 
-void CGUIDialogAddonInfo::OnUninstall()
+bool CGUIDialogAddonInfo::PromptIfDependency(int heading, int line2)
 {
-  if (!m_localAddon.get())
-    return;
+  if (!m_localAddon)
+    return false;
 
-  // ensure the addon is not a dependency of other installed addons
   VECADDONS addons;
-  CStdStringArray deps;
+  vector<string> deps;
   CAddonMgr::Get().GetAllAddons(addons);
-  for (VECADDONS::iterator it  = addons.begin();
-                           it != addons.end();++it)
+  for (VECADDONS::const_iterator it  = addons.begin();
+       it != addons.end();++it)
   {
-    if ((*it)->GetDeps().find(m_localAddon->ID()) != (*it)->GetDeps().end())
+    ADDONDEPS::const_iterator i = (*it)->GetDeps().find(m_localAddon->ID());
+    if (i != (*it)->GetDeps().end() && !i->second.second) // non-optional dependency
       deps.push_back((*it)->Name());
   }
 
-  if (!CAddonInstaller::Get().CheckDependencies(m_localAddon) && deps.size())
+  if (!deps.empty())
   {
-    CStdString strLine0, strLine1;
-    StringUtils::JoinString(deps, ", ", strLine1);
-    strLine0.Format(g_localizeStrings.Get(24046), m_localAddon->Name().c_str());
-    CGUIDialogOK::ShowAndGetInput(24037, strLine0, strLine1, 24047);
-    return;
+    string line0 = StringUtils::Format(g_localizeStrings.Get(24046), m_localAddon->Name().c_str());
+    string line1 = StringUtils::Join(deps, ", ");
+    CGUIDialogOK::ShowAndGetInput(heading, line0, line1, line2);
+    return true;
   }
+  return false;
+}
+
+void CGUIDialogAddonInfo::OnUninstall()
+{
+  if (!m_localAddon.get())
+    return;
+
+  if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
+    return;
+
+  // ensure the addon is not a dependency of other installed addons
+  if (PromptIfDependency(24037, 24047))
+    return;
+
+  // prompt user to be sure
+  if (!CGUIDialogYesNo::ShowAndGetInput(24037, 750, 0, 0))
+    return;
 
   // ensure the addon isn't disabled in our database
   CAddonMgr::Get().DisableAddon(m_localAddon->ID(), false);
@@ -220,6 +238,12 @@ void CGUIDialogAddonInfo::OnEnable(bool enable)
   if (!m_localAddon.get())
     return;
 
+  if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
+    return;
+
+  if (!enable && PromptIfDependency(24075, 24091))
+    return;
+
   CAddonMgr::Get().DisableAddon(m_localAddon->ID(), !enable);
   SetItem(m_item);
   UpdateControls();
@@ -266,6 +290,9 @@ void CGUIDialogAddonInfo::OnChangeLog()
 
 void CGUIDialogAddonInfo::OnRollback()
 {
+  if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
+    return;
+
   CGUIDialogContextMenu* dlg = (CGUIDialogContextMenu*)g_windowManager.GetWindow(WINDOW_DIALOG_CONTEXT_MENU);
   CAddonDatabase database;
   database.Open();
@@ -391,6 +418,8 @@ void CGUIDialogAddonInfo::GrabRollbackVersions()
   CFileItemList items;
   XFILE::CDirectory::GetDirectory("special://home/addons/packages/",items,".zip",DIR_FLAG_NO_FILE_DIRS);
   items.Sort(SortByLabel, SortOrderAscending);
+  CAddonDatabase db;
+  db.Open();
   for (int i=0;i<items.Size();++i)
   {
     if (items[i]->m_bIsFolder)
@@ -398,6 +427,20 @@ void CGUIDialogAddonInfo::GrabRollbackVersions()
     CStdString ID, version;
     AddonVersion::SplitFileName(ID,version,items[i]->GetLabel());
     if (ID.Equals(m_localAddon->ID()))
-      m_rollbackVersions.push_back(version);
+    {
+      CStdString hash, path(items[i]->GetPath());
+      if (db.GetPackageHash(m_localAddon->ID(), path, hash))
+      {
+        CStdString md5 = CUtil::GetFileMD5(path);
+        if (md5 == hash)
+          m_rollbackVersions.push_back(version);
+        else /* The package has been corrupted */
+        {
+          CLog::Log(LOGWARNING, "%s: Removing corrupt addon package %s.", __FUNCTION__, path.c_str());
+          CFile::Delete(path);
+          db.RemovePackage(path);
+        }
+      }
+    }
   }
 }