Commit 1a4c7986 authored by Jason Duell's avatar Jason Duell
Browse files

Bug 786299 - Delete app-cache related to an app when uninstalled, part 1 r=jduell

parent 448fa1fd
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ interface nsILoadContext;
 * The application cache service manages the set of application cache
 * groups.
 */
[scriptable, uuid(F94DB1CC-AB56-480b-8F86-40748878557E)]
[scriptable, uuid(1750F671-0170-4d3f-A836-455501141E32)]
interface nsIApplicationCacheService : nsISupports
{
    /**
@@ -62,6 +62,20 @@ interface nsIApplicationCacheService : nsISupports
     */
    void deactivateGroup(in ACString group);

    /**
     * Deletes some or all of an application's cache entries.  
     *
     * @param appId
     *    The mozIApplication.localId of the application.
     * 
     * @param discardOnlyBrowserEntries 
     *    If true, only entries marked as 'inBrowserElement' are deleted 
     *    (this is used by browser applications to delete user browsing 
     *    data/history.).  If false, *all* entries for the given appId are
     *    deleted (this is used for application uninstallation).
     */
    void discardByAppId(in int32_t appID, in boolean discardOnlyBrowserEntries);

    /**
     * Try to find the best application cache to serve a resource.
     */
+12 −0
Original line number Diff line number Diff line
@@ -129,6 +129,18 @@ nsApplicationCacheService::CacheOpportunistically(nsIApplicationCache* cache,
    return device->CacheOpportunistically(cache, key);
}

NS_IMETHODIMP
nsApplicationCacheService::DiscardByAppId(int32_t appID, bool isInBrowser)
{
    if (!mCacheService)
        return NS_ERROR_UNEXPECTED;

    nsRefPtr<nsOfflineCacheDevice> device;
    nsresult rv = mCacheService->GetOfflineDevice(getter_AddRefs(device));
    NS_ENSURE_SUCCESS(rv, rv);
    return device->DiscardByAppId(appID, isInBrowser);
}

NS_IMETHODIMP
nsApplicationCacheService::GetGroups(uint32_t *count,
                                     char ***keys)
+60 −8
Original line number Diff line number Diff line
@@ -1215,6 +1215,7 @@ nsOfflineCacheDevice::Init()
                                                     " AND NameSpace <= ?2 AND ?2 GLOB NameSpace || '*'"
                                                     " ORDER BY NameSpace DESC;"),
    StatementSql ( mStatement_InsertNamespaceEntry,  "INSERT INTO moz_cache_namespaces (ClientID, NameSpace, Data, ItemType) VALUES(?, ?, ?, ?);"),
    StatementSql ( mStatement_EnumerateApps,         "SELECT GroupID, ActiveClientID FROM moz_cache_groups WHERE GroupID LIKE ?1;"),
    StatementSql ( mStatement_EnumerateGroups,       "SELECT GroupID, ActiveClientID FROM moz_cache_groups;"),
    StatementSql ( mStatement_EnumerateGroupsTimeOrder, "SELECT GroupID, ActiveClientID FROM moz_cache_groups ORDER BY ActivateTimeStamp;")
  };
@@ -1245,6 +1246,17 @@ GetGroupForCache(const nsCSubstring &clientID, nsCString &group)
  return NS_OK;
}

nsresult
AppendJARIdentifier(nsACString &_result, int32_t appId, bool isInBrowserElement)
{
    _result.Append('#');
    _result.AppendInt(appId);
    _result.Append('+');
    _result.Append(isInBrowserElement ? 't' : 'f');

    return NS_OK;
}

nsresult
GetJARIdentifier(nsIURI *aURI,
                 nsILoadContext *aLoadContext,
@@ -1271,11 +1283,7 @@ GetJARIdentifier(nsIURI *aURI,
        return NS_OK;

    // This load context has some special attributes, create a jar identifier
    _result.AppendInt(appId);
    _result.Append('+');
    _result.Append(isInBrowserElement ? 't' : 'f');

    return NS_OK;
    return AppendJARIdentifier(_result, appId, isInBrowserElement);
}

} // anon namespace
@@ -1301,10 +1309,8 @@ nsOfflineCacheDevice::BuildApplicationCacheGroupID(nsIURI *aManifestURL,
  NS_ENSURE_SUCCESS(rv, rv);

  // Include JAR ID, i.e. the extended origin if present.
  if (!jarid.IsEmpty()) {
    _result.Append('#');
  if (!jarid.IsEmpty())
    _result.Append(jarid);
  }

  return NS_OK;
}
@@ -2362,6 +2368,52 @@ nsOfflineCacheDevice::DeactivateGroup(const nsACString &group)
  return NS_OK;
}

nsresult
nsOfflineCacheDevice::DiscardByAppId(int32_t appID, bool browserEntriesOnly)
{
  nsresult rv;

  nsAutoCString jaridsuffix;
  jaridsuffix.Append('%');
  rv = AppendJARIdentifier(jaridsuffix, appID, browserEntriesOnly);
  NS_ENSURE_SUCCESS(rv, rv);

  AutoResetStatement statement(mStatement_EnumerateApps);
  rv = statement->BindUTF8StringByIndex(0, jaridsuffix);
  NS_ENSURE_SUCCESS(rv, rv);

  bool hasRows;
  rv = statement->ExecuteStep(&hasRows);
  NS_ENSURE_SUCCESS(rv, rv);

  while (hasRows) {
    nsAutoCString group;
    rv = statement->GetUTF8String(0, group);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCString clientID;
    rv = statement->GetUTF8String(1, clientID);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIRunnable> ev =
      new nsOfflineCacheDiscardCache(this, group, clientID);

    rv = nsCacheService::DispatchToCacheIOThread(ev);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = statement->ExecuteStep(&hasRows);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  if (!browserEntriesOnly) {
    // If deleting app, delete any 'inBrowserElement' entries too
    rv = DiscardByAppId(appID, true);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  return NS_OK;
}

bool
nsOfflineCacheDevice::CanUseCache(nsIURI *keyURI,
                                  const nsACString &clientID,
+3 −0
Original line number Diff line number Diff line
@@ -158,6 +158,8 @@ public:
  nsresult                CacheOpportunistically(nsIApplicationCache* cache,
                                                 const nsACString &key);

  nsresult                DiscardByAppId(int32_t appID, bool isInBrowser);

  nsresult                GetGroups(uint32_t *count,char ***keys);

  nsresult                GetGroupsTimeOrdered(uint32_t *count,
@@ -257,6 +259,7 @@ private:
  nsCOMPtr<mozIStorageStatement>  mStatement_DeactivateGroup;
  nsCOMPtr<mozIStorageStatement>  mStatement_FindClient;
  nsCOMPtr<mozIStorageStatement>  mStatement_FindClientByNamespace;
  nsCOMPtr<mozIStorageStatement>  mStatement_EnumerateApps;
  nsCOMPtr<mozIStorageStatement>  mStatement_EnumerateGroups;
  nsCOMPtr<mozIStorageStatement>  mStatement_EnumerateGroupsTimeOrder;