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;
7 import java.util.Iterator;
9 import org.json.JSONObject;
10 import org.mozilla.gecko.AppConstants;
11 import org.mozilla.gecko.SysInfo;
12 import org.mozilla.gecko.background.common.GlobalConstants;
13 import org.mozilla.gecko.background.common.log.Logger;
15 import android.content.ContentProvider;
16 import android.content.ContentProviderClient;
17 import android.content.ContentResolver;
18 import android.content.Context;
20 /**
21 * Construct a HealthReport environment from the current running system.
22 */
23 public class EnvironmentBuilder {
24 private static final String LOG_TAG = "GeckoEnvBuilder";
26 public static ContentProviderClient getContentProviderClient(Context context) {
27 ContentResolver cr = context.getContentResolver();
28 return cr.acquireContentProviderClient(HealthReportConstants.HEALTH_AUTHORITY);
29 }
31 /**
32 * Fetch the storage object associated with the provided
33 * {@link ContentProviderClient}. If no storage instance can be found --
34 * perhaps because the {@link ContentProvider} is running in a different
35 * process -- returns <code>null</code>. On success, the returned
36 * {@link HealthReportDatabaseStorage} instance is owned by the underlying
37 * {@link HealthReportProvider} and thus does not need to be closed by the
38 * caller.
39 *
40 * If the provider is not a {@link HealthReportProvider}, throws a
41 * {@link ClassCastException}, because that would be disastrous.
42 */
43 public static HealthReportDatabaseStorage getStorage(ContentProviderClient cpc,
44 String profilePath) {
45 ContentProvider pr = cpc.getLocalContentProvider();
46 if (pr == null) {
47 Logger.error(LOG_TAG, "Unable to retrieve local content provider. Running in a different process?");
48 return null;
49 }
50 try {
51 return ((HealthReportProvider) pr).getProfileStorage(profilePath);
52 } catch (ClassCastException ex) {
53 Logger.error(LOG_TAG, "ContentProvider not a HealthReportProvider!", ex);
54 throw ex;
55 }
56 }
58 public static interface ProfileInformationProvider {
59 public boolean isBlocklistEnabled();
60 public boolean isTelemetryEnabled();
61 public boolean isAcceptLangUserSet();
62 public long getProfileCreationTime();
64 public String getDistributionString();
65 public String getOSLocale();
66 public String getAppLocale();
68 public JSONObject getAddonsJSON();
69 }
71 protected static void populateEnvironment(Environment e,
72 ProfileInformationProvider info) {
73 e.cpuCount = SysInfo.getCPUCount();
74 e.memoryMB = SysInfo.getMemSize();
76 e.appName = AppConstants.MOZ_APP_NAME;
77 e.appID = AppConstants.MOZ_APP_ID;
78 e.appVersion = AppConstants.MOZ_APP_VERSION;
79 e.appBuildID = AppConstants.MOZ_APP_BUILDID;
80 e.updateChannel = AppConstants.MOZ_UPDATE_CHANNEL;
81 e.vendor = AppConstants.MOZ_APP_VENDOR;
82 e.platformVersion = AppConstants.MOZILLA_VERSION;
83 e.platformBuildID = AppConstants.MOZ_APP_BUILDID;
84 e.xpcomabi = AppConstants.TARGET_XPCOM_ABI;
85 e.os = "Android";
86 e.architecture = SysInfo.getArchABI(); // Not just "arm".
87 e.sysName = SysInfo.getName();
88 e.sysVersion = SysInfo.getReleaseVersion();
90 e.profileCreation = (int) (info.getProfileCreationTime() / GlobalConstants.MILLISECONDS_PER_DAY);
92 // Corresponds to Gecko pref "extensions.blocklist.enabled".
93 e.isBlocklistEnabled = (info.isBlocklistEnabled() ? 1 : 0);
95 // Corresponds to Gecko pref "toolkit.telemetry.enabled".
96 e.isTelemetryEnabled = (info.isTelemetryEnabled() ? 1 : 0);
98 e.extensionCount = 0;
99 e.pluginCount = 0;
100 e.themeCount = 0;
102 JSONObject addons = info.getAddonsJSON();
103 if (addons == null) {
104 return;
105 }
107 @SuppressWarnings("unchecked")
108 Iterator<String> it = addons.keys();
109 while (it.hasNext()) {
110 String key = it.next();
111 try {
112 JSONObject addon = addons.getJSONObject(key);
113 String type = addon.optString("type");
114 Logger.pii(LOG_TAG, "Add-on " + key + " is a " + type);
115 if ("extension".equals(type)) {
116 ++e.extensionCount;
117 } else if ("plugin".equals(type)) {
118 ++e.pluginCount;
119 } else if ("theme".equals(type)) {
120 ++e.themeCount;
121 } else if ("service".equals(type)) {
122 // Later.
123 } else {
124 Logger.debug(LOG_TAG, "Unknown add-on type: " + type);
125 }
126 } catch (Exception ex) {
127 Logger.warn(LOG_TAG, "Failed to process add-on " + key, ex);
128 }
129 }
131 e.addons = addons;
133 // v2 environment fields.
134 e.distribution = info.getDistributionString();
135 e.osLocale = info.getOSLocale();
136 e.appLocale = info.getAppLocale();
137 e.acceptLangSet = info.isAcceptLangUserSet() ? 1 : 0;
138 }
140 /**
141 * Returns an {@link Environment} not linked to a storage instance, but
142 * populated with current field values.
143 *
144 * @param info a source of profile data
145 * @return the new {@link Environment}
146 */
147 public static Environment getCurrentEnvironment(ProfileInformationProvider info) {
148 Environment e = new Environment() {
149 @Override
150 public int register() {
151 return 0;
152 }
153 };
154 populateEnvironment(e, info);
155 return e;
156 }
158 /**
159 * @return the current environment's ID in the provided storage layer
160 */
161 public static int registerCurrentEnvironment(final HealthReportStorage storage,
162 final ProfileInformationProvider info) {
163 Environment e = storage.getEnvironment();
164 populateEnvironment(e, info);
165 e.register();
166 Logger.debug(LOG_TAG, "Registering current environment: " + e.getHash() + " = " + e.id);
167 return e.id;
168 }
169 }