Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java

Issue 839663003: Upstream partner customizations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed tests Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.partnercustomizations;
6
7 import android.content.ContentResolver;
8 import android.content.Context;
9 import android.content.pm.ApplicationInfo;
10 import android.content.pm.ProviderInfo;
11 import android.database.Cursor;
12 import android.net.Uri;
13 import android.os.AsyncTask;
14 import android.text.TextUtils;
15 import android.util.Log;
16
17 import org.chromium.base.ThreadUtils;
18 import org.chromium.base.VisibleForTesting;
19 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksReader;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 /**
25 * Reads and caches partner browser customizations information if it exists.
26 */
27 public class PartnerBrowserCustomizations {
28 private static final String TAG = "PartnerBrowserProvider";
29 private static final String PROVIDER_AUTHORITY = "com.android.partnerbrowser customizations";
30
31 // Private homepage structure.
32 static final String PARTNER_HOMEPAGE_PATH = "homepage";
33 static final String PARTNER_DISABLE_BOOKMARKS_EDITING_PATH = "disablebookmar ksediting";
34 @VisibleForTesting
35 public static final String PARTNER_DISABLE_INCOGNITO_MODE_PATH = "disableinc ognitomode";
36
37 private static String sProviderAuthority = PROVIDER_AUTHORITY;
38 private static boolean sIgnoreBrowserProviderSystemPackageCheck = false;
39 private static volatile String sHomepage;
40 private static volatile boolean sIncognitoModeDisabled;
41 private static volatile boolean sBookmarksEditingDisabled;
42 private static boolean sIsInitialized;
43 private static List<Runnable> sInitializeAsyncCallbacks = new ArrayList<Runn able>();
44
45 /**
46 * @return True if the partner homepage content provider exists and enabled. Note that The data
47 * this method reads is not initialized until the asynchronous initi alization of this
48 * class has been completed.
49 */
50 public static boolean isHomepageProviderAvailableAndEnabled() {
51 return !TextUtils.isEmpty(getHomePageUrl());
52 }
53
54 /**
55 * @return Whether incognito mode is disabled by the partner.
56 */
57 public static boolean isIncognitoDisabled() {
58 return sIncognitoModeDisabled;
59 }
60
61 /**
62 * @return Whether partner bookmarks editing is disabled by the partner.
63 */
64 @VisibleForTesting
65 static boolean isBookmarksEditingDisabled() {
66 return sBookmarksEditingDisabled;
67 }
68
69 /**
70 * @return True, if initialization is finished. Checking that there is no pr ovider, or failing
71 * to read provider is also considered initialization.
72 */
73 @VisibleForTesting
74 static boolean isInitialized() {
75 return sIsInitialized;
76 }
77
78 @VisibleForTesting
79 public static void setProviderAuthorityForTests(String providerAuthority) {
80 sProviderAuthority = providerAuthority;
81 }
82
83 /**
84 * For security, we only allow system package to be a browser customizations provider. However,
85 * requiring root and installing system apk makes testing harder, so we deci ded to have this
86 * hack for testing. This must not be called other than tests.
87 *
88 * @param ignore whether we should ignore browser provider system package ch ecking.
89 */
90 @VisibleForTesting
91 public static void ignoreBrowserProviderSystemPackageCheckForTests(boolean i gnore) {
92 sIgnoreBrowserProviderSystemPackageCheck = ignore;
93 }
94
95 @VisibleForTesting
96 public static Uri buildQueryUri(String path) {
97 return new Uri.Builder()
98 .scheme("content")
99 .authority(sProviderAuthority)
100 .appendPath(path)
101 .build();
102 }
103
104 /**
105 * Constructs an async task that reads PartnerBrowserCustomization provider.
106 *
107 * @param context The current application context.
108 * @param timeoutMs If initializing takes more than this time, cancels it. T he unit is ms.
109 */
110 public static void initializeAsync(final Context context, long timeoutMs) {
111 sIsInitialized = false;
112 // Setup an initializing async task.
113 final AsyncTask<Void, Void, Void> initializeAsyncTask =
114 new AsyncTask<Void, Void, Void>() {
115 private boolean mDisablePartnerBookmarksShim;
116 private boolean mHomepageUriChanged;
117
118 private void refreshHomepage() {
119 try {
120 ContentResolver contentResolver = context.getContentResolver ();
121 Cursor cursor = contentResolver.query(
122 buildQueryUri(PARTNER_HOMEPAGE_PATH), null, null, nu ll, null);
123 if (cursor != null && cursor.moveToFirst() && cursor.getColu mnCount() == 1
124 && !isCancelled()) {
125 if (TextUtils.isEmpty(sHomepage)
126 || !sHomepage.equals(cursor.getString(0))) {
127 mHomepageUriChanged = true;
128 }
129 sHomepage = cursor.getString(0);
130 }
131 if (cursor != null) cursor.close();
132 } catch (Exception e) {
133 Log.w(TAG, "Partner homepage provider URL read failed : ", e );
134 }
135 }
136
137 private void refreshIncognitoModeDisabled() {
138 try {
139 ContentResolver contentResolver = context.getContentResolver ();
140 Cursor cursor = contentResolver.query(
141 buildQueryUri(PARTNER_DISABLE_INCOGNITO_MODE_PATH),
142 null, null, null, null);
143 if (cursor != null && cursor.moveToFirst() && cursor.getColu mnCount() == 1
144 && !isCancelled()) {
145 sIncognitoModeDisabled = cursor.getInt(0) == 1;
146 }
147 if (cursor != null) cursor.close();
148 } catch (Exception e) {
149 Log.w(TAG, "Partner disable incognito mode read failed : ", e);
150 }
151 }
152
153 private void refreshBookmarksEditingDisabled() {
154 try {
155 ContentResolver contentResolver = context.getContentResolver ();
156 Cursor cursor = contentResolver.query(
157 buildQueryUri(PARTNER_DISABLE_BOOKMARKS_EDITING_PATH ),
158 null, null, null, null);
159 if (cursor != null && cursor.moveToFirst() && cursor.getColu mnCount() == 1
160 && !isCancelled()) {
161 boolean bookmarksEditingDisabled = cursor.getInt(0) == 1 ;
162 if (bookmarksEditingDisabled != sBookmarksEditingDisable d) {
163 mDisablePartnerBookmarksShim = true;
164 }
165 sBookmarksEditingDisabled = bookmarksEditingDisabled;
166 }
167 if (cursor != null) cursor.close();
168 } catch (Exception e) {
169 Log.w(TAG, "Partner disable bookmarks editing read failed : ", e);
170 }
171 }
172
173 @Override
174 protected Void doInBackground(Void... params) {
175 try {
176 ProviderInfo providerInfo = context.getPackageManager()
177 .resolveContentProvider(sProviderAuthority, 0);
178 if (providerInfo == null) return null;
179
180 if ((providerInfo.applicationInfo.flags & ApplicationInfo.FL AG_SYSTEM) == 0
181 && !sIgnoreBrowserProviderSystemPackageCheck) {
182 Log.w("TAG", "Browser Cutomizations content provider pac kage, "
183 + providerInfo.packageName + ", is not a system package. "
184 + "This could be a malicious attepment from a th ird party app, "
185 + "so skip reading the browser content provider. ");
186 return null;
187 }
188
189 if (isCancelled()) return null;
190 refreshIncognitoModeDisabled();
191
192 if (isCancelled()) return null;
193 refreshBookmarksEditingDisabled();
194
195 if (isCancelled()) return null;
196 refreshHomepage();
197 } catch (Exception e) {
198 Log.w(TAG, "Fetching partner customizations failed", e);
199 }
200 return null;
201 }
202
203 @Override
204 protected void onPostExecute(Void result) {
205 onFinalized();
206 }
207
208 @Override
209 protected void onCancelled(Void result) {
210 onFinalized();
211 }
212
213 private void onFinalized() {
214 sIsInitialized = true;
215
216 for (Runnable callback : sInitializeAsyncCallbacks) {
217 callback.run();
218 }
219 sInitializeAsyncCallbacks.clear();
220
221 if (mHomepageUriChanged) {
222 HomepageManager.getInstance(context).notifyHomepageUpdated() ;
223 }
224
225 // Disable partner bookmarks editing if necessary.
226 if (mDisablePartnerBookmarksShim) {
227 PartnerBookmarksReader.disablePartnerBookmarksEditing();
228 }
229 }
230 };
231
232 initializeAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
233
234 // Cancel the initialization if it reaches timeout.
235 ThreadUtils.postOnUiThreadDelayed(new Runnable() {
236 @Override
237 public void run() {
238 initializeAsyncTask.cancel(true);
239 }
240 }, timeoutMs);
241 }
242
243 /**
244 * Sets a callback that will be executed when the initialization is done.
245 *
246 * @param callback This is called when the initialization is done.
247 */
248 public static void setOnInitializeAsyncFinished(final Runnable callback) {
249 if (sIsInitialized) {
250 ThreadUtils.postOnUiThread(callback);
251 } else {
252 sInitializeAsyncCallbacks.add(callback);
253 }
254 }
255
256 /**
257 * Sets a callback that will be executed when the initialization is done.
258 *
259 * @param callback This is called when the initialization is done.
260 * @param timeoutMs If initializing takes more than this time since this fun ction is called,
261 * force run |callback| early. The unit is ms.
262 */
263 public static void setOnInitializeAsyncFinished(final Runnable callback, lon g timeoutMs) {
264 sInitializeAsyncCallbacks.add(callback);
265
266 ThreadUtils.postOnUiThreadDelayed(
267 new Runnable() {
268 @Override
269 public void run() {
270 if (sInitializeAsyncCallbacks.remove(callback)) callback .run();
271 }
272 },
273 sIsInitialized ? 0 : timeoutMs);
274 }
275
276 public static void destroy() {
277 sIsInitialized = false;
278 sInitializeAsyncCallbacks.clear();
279 sHomepage = null;
280 }
281
282 /**
283 * @return Home page URL from Android provider. If null, that means either t here is no homepage
284 * provider or provider set it to null to disable homepage.
285 */
286 public static String getHomePageUrl() {
287 return sHomepage;
288 }
289 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698