Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 package org.mozilla.gecko.background.healthreport.prune;
7 import org.mozilla.gecko.background.common.log.Logger;
8 import org.mozilla.gecko.background.healthreport.Environment;
9 import org.mozilla.gecko.background.healthreport.EnvironmentBuilder;
10 import org.mozilla.gecko.background.healthreport.HealthReportDatabaseStorage;
11 import org.mozilla.gecko.background.healthreport.ProfileInformationCache;
13 import android.content.ContentProviderClient;
14 import android.content.Context;
16 /**
17 * Abstracts over the Storage instance behind the PrunePolicy. The underlying storage instance is
18 * a {@link HealthReportDatabaseStorage} instance. Since our cleanup routine vacuums, auto_vacuum
19 * can be disabled. It is enabled by default, however, turning it off requires an expensive vacuum
20 * so we wait until our first {@link cleanup} call since we are vacuuming anyway.
21 */
22 public class PrunePolicyDatabaseStorage implements PrunePolicyStorage {
23 public static final String LOG_TAG = PrunePolicyDatabaseStorage.class.getSimpleName();
25 private final Context context;
26 private final String profilePath;
28 private ContentProviderClient client;
29 private HealthReportDatabaseStorage storage;
31 private int currentEnvironmentID; // So we don't prune the current environment.
33 public PrunePolicyDatabaseStorage(final Context context, final String profilePath) {
34 this.context = context;
35 this.profilePath = profilePath;
37 this.currentEnvironmentID = -1;
38 }
40 public void pruneEvents(final int count) {
41 getStorage().pruneEvents(count);
42 }
44 public void pruneEnvironments(final int count) {
45 getStorage().pruneEnvironments(count);
47 // Re-populate the DB and environment cache with the current environment in the unlikely event
48 // that it was deleted.
49 this.currentEnvironmentID = -1;
50 getCurrentEnvironmentID();
51 }
53 /**
54 * Deletes data recorded before the given time. Note that if this method fails to retrieve the
55 * current environment from the profile cache, it will not delete data so be sure to prune by
56 * other methods (e.g. {@link pruneEvents}) as well.
57 */
58 public int deleteDataBefore(final long time) {
59 return getStorage().deleteDataBefore(time, getCurrentEnvironmentID());
60 }
62 public void cleanup() {
63 final HealthReportDatabaseStorage storage = getStorage();
64 // The change to auto_vacuum will only take affect after a vacuum.
65 storage.disableAutoVacuuming();
66 storage.vacuum();
67 }
69 public int getEventCount() {
70 return getStorage().getEventCount();
71 }
73 public int getEnvironmentCount() {
74 return getStorage().getEnvironmentCount();
75 }
77 public void close() {
78 if (client != null) {
79 client.release();
80 client = null;
81 }
82 }
84 /**
85 * Retrieves the {@link HealthReportDatabaseStorage} associated with the profile of the policy.
86 * For efficiency, the underlying {@link ContentProviderClient} and
87 * {@link HealthReportDatabaseStorage} are cached for later invocations. However, this means a
88 * call to this method MUST be accompanied by a call to {@link close}. Throws
89 * {@link IllegalStateException} if the storage instance could not be retrieved - note that the
90 * {@link ContentProviderClient} instance will not be closed in this case and
91 * {@link releaseClient} should still be called.
92 */
93 protected HealthReportDatabaseStorage getStorage() {
94 if (storage != null) {
95 return storage;
96 }
98 client = EnvironmentBuilder.getContentProviderClient(context);
99 if (client == null) {
100 // TODO: Record prune failures and submit as part of FHR upload.
101 Logger.warn(LOG_TAG, "Unable to get ContentProviderClient - throwing.");
102 throw new IllegalStateException("Unable to get ContentProviderClient.");
103 }
105 try {
106 storage = EnvironmentBuilder.getStorage(client, profilePath);
107 if (storage == null) {
108 // TODO: Record prune failures and submit as part of FHR upload.
109 Logger.warn(LOG_TAG,"Unable to get HealthReportDatabaseStorage for " + profilePath +
110 " - throwing.");
111 throw new IllegalStateException("Unable to get HealthReportDatabaseStorage for " +
112 profilePath + " (== null).");
113 }
114 } catch (ClassCastException ex) {
115 // TODO: Record prune failures and submit as part of FHR upload.
116 Logger.warn(LOG_TAG,"Unable to get HealthReportDatabaseStorage for " + profilePath +
117 profilePath + " (ClassCastException).");
118 throw new IllegalStateException("Unable to get HealthReportDatabaseStorage for " +
119 profilePath + ".", ex);
120 }
122 return storage;
123 }
125 protected int getCurrentEnvironmentID() {
126 if (currentEnvironmentID < 0) {
127 final ProfileInformationCache cache = new ProfileInformationCache(profilePath);
128 if (!cache.restoreUnlessInitialized()) {
129 throw new IllegalStateException("Current environment unknown.");
130 }
131 final Environment env = EnvironmentBuilder.getCurrentEnvironment(cache);
132 currentEnvironmentID = env.register();
133 }
134 return currentEnvironmentID;
135 }
136 }