[addonmgr] query addon disabled state once and cache it (fixes #14122)
authorvdrfan <vdrfan@xbmc.org>
Sat, 19 Oct 2013 09:29:00 +0000 (11:29 +0200)
committervdrfan <vdrfan@xbmc.org>
Sun, 20 Oct 2013 08:27:01 +0000 (10:27 +0200)
This implements DisableAddon and IsAddonDisabled in AddonMgr. Both functions will trigger the database routines
and cache the current addon state instead of doing the database query again. In case the disabled cache does not
know about the current state the database routine will be used to retrieve it.

xbmc/addons/AddonInstaller.cpp
xbmc/addons/AddonManager.cpp
xbmc/addons/AddonManager.h
xbmc/addons/GUIDialogAddonInfo.cpp
xbmc/addons/Repository.cpp
xbmc/filesystem/AddonsDirectory.cpp
xbmc/interfaces/json-rpc/AddonsOperations.cpp
xbmc/pvr/PVRDatabase.cpp
xbmc/pvr/addons/PVRClients.cpp

index d016089..59819aa 100644 (file)
@@ -578,10 +578,8 @@ bool CAddonInstallJob::OnPreInstall()
 
   if (m_addon->Type() == ADDON_SERVICE)
   {
-    CAddonDatabase database;
-    database.Open();
-    bool running = !database.IsAddonDisabled(m_addon->ID()); //grab a current state
-    database.DisableAddon(m_addon->ID(),false); // enable it so we can remove it??
+    bool running = !CAddonMgr::Get().IsAddonDisabled(m_addon->ID()); //grab a current state
+    CAddonMgr::Get().DisableAddon(m_addon->ID(),false); // enable it so we can remove it??
     // regrab from manager to have the correct path set
     AddonPtr addon;
     ADDON::CAddonMgr::Get().GetAddon(m_addon->ID(), addon);
@@ -710,9 +708,7 @@ void CAddonInstallJob::OnPostInstall(bool reloadAddon)
 
   if (m_addon->Type() == ADDON_SERVICE)
   {
-    CAddonDatabase database;
-    database.Open();
-    database.DisableAddon(m_addon->ID(),!reloadAddon); //return it into state it was before OnPreInstall()
+    CAddonMgr::Get().DisableAddon(m_addon->ID(),!reloadAddon); //return it into state it was before OnPreInstall()
     if (reloadAddon) // reload/start it if it was running
     {
       // regrab from manager to have the correct path set
index c05e602..cf0a202 100644 (file)
@@ -420,7 +420,7 @@ bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, bool enabled /* =
   for(int i=0; i <num; i++)
   {
     const cp_extension_t *props = exts[i];
-    if (m_database.IsAddonDisabled(props->plugin->identifier) != enabled)
+    if (IsAddonDisabled(props->plugin->identifier) != enabled)
     {
       // get a pointer to a running pvrclient if it's already started, or we won't be able to change settings
       if (TranslateType(props->ext_point_id) == ADDON_PVRDLL &&
@@ -457,7 +457,7 @@ bool CAddonMgr::GetAddon(const CStdString &str, AddonPtr &addon, const TYPE &typ
 
     if (addon && addon.get())
     {
-      if (enabledOnly && m_database.IsAddonDisabled(addon->ID()))
+      if (enabledOnly && IsAddonDisabled(addon->ID()))
         return false;
 
       if (addon->Type() == ADDON_PVRDLL && g_PVRManager.IsStarted())
@@ -575,6 +575,31 @@ void CAddonMgr::RemoveAddon(const CStdString& ID)
   }
 }
 
+bool CAddonMgr::DisableAddon(const std::string& ID, bool disable)
+{
+  CSingleLock lock(m_critSection);
+  if (m_database.DisableAddon(ID, disable))
+  {
+    m_disabled[ID] = disable;
+    return true;
+  }
+
+  return false;
+}
+
+bool CAddonMgr::IsAddonDisabled(const std::string& ID)
+{
+  CSingleLock lock(m_critSection);
+  std::map<std::string, bool>::const_iterator it = m_disabled.find(ID);
+  if (it != m_disabled.end())
+    return it->second;
+
+  bool ret = m_database.IsAddonDisabled(ID);
+  m_disabled.insert(pair<std::string, bool>(ID, ret));
+
+  return ret;
+}
+
 const char *CAddonMgr::GetTranslatedString(const cp_cfg_element_t *root, const char *tag)
 {
   if (!root)
index bfcfb22..7349966 100644 (file)
@@ -115,6 +115,21 @@ namespace ADDON
     void FindAddons();
     void RemoveAddon(const CStdString& ID);
 
+    /* \brief Disable an addon
+     Triggers the database routine and saves the current addon state to cache.
+     \param ID id of the addon
+     \param disable whether to enable or disable. Defaults to true (disable)
+     \sa IsAddonDisabled,
+     */
+    bool DisableAddon(const std::string& ID, bool disable = true);
+
+    /* \brief Check whether an addon has been disabled via DisableAddon.
+     In case the disabled cache does not know about the current state the database routine will be used.
+     \param ID id of the addon
+     \sa DisableAddon
+     */
+    bool IsAddonDisabled(const std::string& ID);
+
     /* libcpluff */
     CStdString GetExtValue(cp_cfg_element_t *base, const char *path);
 
@@ -203,6 +218,7 @@ namespace ADDON
     CAddonMgr const& operator=(CAddonMgr const&);
     virtual ~CAddonMgr();
 
+    std::map<std::string, bool> m_disabled;
     static std::map<TYPE, IAddonMgrCallback*> m_managers;
     CCriticalSection m_critSection;
     CAddonDatabase m_database;
index 1d4d942..a17d23b 100644 (file)
@@ -207,9 +207,8 @@ void CGUIDialogAddonInfo::OnUninstall()
   }
 
   // ensure the addon isn't disabled in our database
-  CAddonDatabase database;
-  database.Open();
-  database.DisableAddon(m_localAddon->ID(), false);
+  CAddonMgr::Get().DisableAddon(m_localAddon->ID(), false);
+
   CJobManager::GetInstance().AddJob(new CAddonUnInstallJob(m_localAddon),
                                     &CAddonInstaller::Get());
   CAddonMgr::Get().RemoveAddon(m_localAddon->ID());
@@ -221,12 +220,7 @@ void CGUIDialogAddonInfo::OnEnable(bool enable)
   if (!m_localAddon.get())
     return;
 
-  CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc/addons");
-  CAddonDatabase database;
-  database.Open();
-  database.DisableAddon(m_localAddon->ID(), !enable);
-  database.Close();
-
+  CAddonMgr::Get().DisableAddon(m_localAddon->ID(), !enable);
   SetItem(m_item);
   UpdateControls();
   g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE);
index 0e96bf0..fed9b96 100644 (file)
@@ -250,7 +250,7 @@ bool CRepositoryUpdateJob::DoWork()
                                              g_localizeStrings.Get(24096),
                                              g_localizeStrings.Get(24097),
                                              ""))
-          database.DisableAddon(addons[i]->ID());
+          CAddonMgr::Get().DisableAddon(addons[i]->ID());
       }
     }
     database.BreakAddon(addons[i]->ID(), addons[i]->Props().broken);
index d8e905d..75d7816 100644 (file)
@@ -203,8 +203,6 @@ void CAddonsDirectory::GenerateListing(CURL &path, VECADDONS& addons, CFileItemL
 {
   CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc/addons");
   items.ClearItems();
-  CAddonDatabase db;
-  db.Open();
   for (unsigned i=0; i < addons.size(); i++)
   {
     AddonPtr addon = addons[i];
@@ -216,7 +214,7 @@ void CAddonsDirectory::GenerateListing(CURL &path, VECADDONS& addons, CFileItemL
     AddonPtr addon2;
     if (CAddonMgr::Get().GetAddon(addon->ID(),addon2))
       pItem->SetProperty("Addon.Status",g_localizeStrings.Get(305));
-    else if (db.IsOpen() && db.IsAddonDisabled(addon->ID()))
+    else if (CAddonMgr::Get().IsAddonDisabled(addon->ID()))
       pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24023));
 
     if (!addon->Props().broken.IsEmpty())
@@ -229,7 +227,6 @@ void CAddonsDirectory::GenerateListing(CURL &path, VECADDONS& addons, CFileItemL
     CAddonDatabase::SetPropertiesFromAddon(addon,pItem);
     items.Add(pItem);
   }
-  db.Close();
 }
 
 CFileItemPtr CAddonsDirectory::FileItemFromAddon(AddonPtr &addon, const CStdString &basePath, bool folder)
index 08afc7d..6bbfd8d 100644 (file)
@@ -142,21 +142,17 @@ JSONRPC_STATUS CAddonsOperations::GetAddonDetails(const CStdString &method, ITra
 
 JSONRPC_STATUS CAddonsOperations::SetAddonEnabled(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  CAddonDatabase addondatabase;
-  if (!addondatabase.Open())
-    return InternalError;
-
   string id = parameterObject["addonid"].asString();
   bool disabled = false;
   if (parameterObject["enabled"].isBoolean())
     disabled = !parameterObject["enabled"].asBoolean();
   // we need to toggle the current disabled state of the addon
   else if (parameterObject["enabled"].isString())
-    disabled = !addondatabase.IsAddonDisabled(id);
+    disabled = !CAddonMgr::Get().IsAddonDisabled(id);
   else
     return InvalidParams;
 
-  if (!addondatabase.DisableAddon(id, disabled))
+  if (!CAddonMgr::Get().DisableAddon(id, disabled))
       return InvalidParams;
 
   return ACK;
@@ -221,9 +217,7 @@ void CAddonsOperations::FillDetails(AddonPtr addon, const CVariant& fields, CVar
     // from the addon database because it can't be read from addon.xml
     if (field == "enabled")
     {
-      if (!addondb.IsOpen() && !addondb.Open())
-        return;
-      object[field] = !addondb.IsAddonDisabled(addon->ID());
+      object[field] = !CAddonMgr::Get().IsAddonDisabled(addon->ID());
     }
     else if (field == "fanart" || field == "thumbnail")
     {
index 34c1a6e..54bc0ea 100644 (file)
@@ -176,11 +176,8 @@ bool CPVRDatabase::CreateTables()
       CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__);
     else
     {
-      CAddonDatabase database;
-      database.Open();
       for (IVECADDONS it = addons.begin(); it != addons.end(); it++)
-        database.DisableAddon(it->get()->ID());
-      database.Close();
+        CAddonMgr::Get().DisableAddon(it->get()->ID());
     }
   }
 
@@ -253,7 +250,7 @@ bool CPVRDatabase::UpdateOldVersion(int iVersion)
           for (IVECADDONS it = addons.begin(); it != addons.end(); it++)
           {
             if (!database.IsSystemPVRAddonEnabled(it->get()->ID()))
-              database.DisableAddon(it->get()->ID());
+              CAddonMgr::Get().DisableAddon(it->get()->ID());
           }
           database.Close();
         }
index aab6345..5aaf881 100644 (file)
@@ -894,7 +894,7 @@ bool CPVRClients::UpdateAndInitialiseClients(bool bInitialiseAllClients /* = fal
   {
     const AddonPtr clientAddon = map.at(iClientPtr);
     bool bEnabled = clientAddon->Enabled() &&
-        !m_addonDb.IsAddonDisabled(clientAddon->ID());
+        !CAddonMgr::Get().IsAddonDisabled(clientAddon->ID());
 
     if (!bEnabled && IsKnownClient(clientAddon))
     {
@@ -970,7 +970,7 @@ bool CPVRClients::UpdateAndInitialiseClients(bool bInitialiseAllClients /* = fal
     for (ADDON::VECADDONS::iterator it = disableAddons.begin(); it != disableAddons.end(); it++)
     {
       // disable in the add-on db
-      m_addonDb.DisableAddon((*it)->ID(), true);
+      CAddonMgr::Get().DisableAddon((*it)->ID(), true);
 
       // remove from the pvr add-on list
       ADDON::VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), *it);