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

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/installedapp/InstalledAppProviderImpl.java

Issue 2813153002: getInstalledRelatedApps: Avoid blocking the UI thread doing computation. (Closed)
Patch Set: Respond to review. Created 3 years, 8 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
« no previous file with comments | « no previous file | content/public/android/junit/src/org/chromium/content/browser/installedapp/InstalledAppProviderTest.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.content.browser.installedapp; 5 package org.chromium.content.browser.installedapp;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.content.pm.ApplicationInfo; 8 import android.content.pm.ApplicationInfo;
9 import android.content.pm.PackageManager; 9 import android.content.pm.PackageManager;
10 import android.content.pm.PackageManager.NameNotFoundException; 10 import android.content.pm.PackageManager.NameNotFoundException;
11 import android.content.res.Resources; 11 import android.content.res.Resources;
12 import android.os.AsyncTask;
12 13
13 import org.json.JSONArray; 14 import org.json.JSONArray;
14 import org.json.JSONException; 15 import org.json.JSONException;
15 import org.json.JSONObject; 16 import org.json.JSONObject;
16 17
17 import org.chromium.base.Log; 18 import org.chromium.base.Log;
18 import org.chromium.base.VisibleForTesting; 19 import org.chromium.base.VisibleForTesting;
19 import org.chromium.installedapp.mojom.InstalledAppProvider; 20 import org.chromium.installedapp.mojom.InstalledAppProvider;
20 import org.chromium.installedapp.mojom.RelatedApplication; 21 import org.chromium.installedapp.mojom.RelatedApplication;
21 import org.chromium.mojo.system.MojoException; 22 import org.chromium.mojo.system.MojoException;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 public boolean isIncognito(); 62 public boolean isIncognito();
62 } 63 }
63 64
64 public InstalledAppProviderImpl(FrameUrlDelegate frameUrlDelegate, Context c ontext) { 65 public InstalledAppProviderImpl(FrameUrlDelegate frameUrlDelegate, Context c ontext) {
65 mFrameUrlDelegate = frameUrlDelegate; 66 mFrameUrlDelegate = frameUrlDelegate;
66 mContext = context; 67 mContext = context;
67 } 68 }
68 69
69 @Override 70 @Override
70 public void filterInstalledApps( 71 public void filterInstalledApps(
71 RelatedApplication[] relatedApps, FilterInstalledAppsResponse callba ck) { 72 final RelatedApplication[] relatedApps, final FilterInstalledAppsRes ponse callback) {
72 if (mFrameUrlDelegate.isIncognito()) { 73 if (mFrameUrlDelegate.isIncognito()) {
73 callback.call(new RelatedApplication[0]); 74 callback.call(new RelatedApplication[0]);
74 return; 75 return;
75 } 76 }
76 77
77 URI frameUrl = mFrameUrlDelegate.getUrl(); 78 final URI frameUrl = mFrameUrlDelegate.getUrl();
79
80 // Use an AsyncTask to execute the installed/related checks on a backgro und thread (so as
81 // not to block the UI thread).
82 new AsyncTask<Void, Void, RelatedApplication[]>() {
83 @Override
84 protected RelatedApplication[] doInBackground(Void... unused) {
85 return filterInstalledAppsOnBackgroundThread(relatedApps, frameU rl);
86 }
87
88 @Override
89 protected void onPostExecute(RelatedApplication[] installedApps) {
90 callback.call(installedApps);
91 }
92 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
93 }
94
95 @Override
96 public void close() {}
97
98 @Override
99 public void onConnectionError(MojoException e) {}
100
101 /**
102 * Filters a list of apps, returning those that are both installed and match the origin.
103 *
104 * This method is expected to be called on a background thread (not the main UI thread).
105 *
106 * @param relatedApps A list of applications to be filtered.
107 * @param frameUrl The URL of the frame this operation was called from.
108 * @return A subsequence of applications that meet the criteria.
109 */
110 private RelatedApplication[] filterInstalledAppsOnBackgroundThread(
111 RelatedApplication[] relatedApps, URI frameUrl) {
78 ArrayList<RelatedApplication> installedApps = new ArrayList<RelatedAppli cation>(); 112 ArrayList<RelatedApplication> installedApps = new ArrayList<RelatedAppli cation>();
79 PackageManager pm = mContext.getPackageManager(); 113 PackageManager pm = mContext.getPackageManager();
80 for (RelatedApplication app : relatedApps) { 114 for (RelatedApplication app : relatedApps) {
81 // If the package is of type "play", it is installed, and the origin is associated with 115 // If the package is of type "play", it is installed, and the origin is associated with
82 // package, add the package to the list of valid packages. 116 // package, add the package to the list of valid packages.
83 // NOTE: For security, it must not be possible to distinguish (from the response) 117 // NOTE: For security, it must not be possible to distinguish (from the response)
84 // between the app not being installed and the origin not being asso ciated with the app 118 // between the app not being installed and the origin not being asso ciated with the app
85 // (otherwise, arbitrary websites would be able to test whether un-a ssociated apps are 119 // (otherwise, arbitrary websites would be able to test whether un-a ssociated apps are
86 // installed on the user's device). 120 // installed on the user's device).
87 if (app.platform.equals(RELATED_APP_PLATFORM_ANDROID) && app.id != n ull 121 if (app.platform.equals(RELATED_APP_PLATFORM_ANDROID) && app.id != n ull
88 && isAppInstalledAndAssociatedWithOrigin(app.id, frameUrl, p m)) { 122 && isAppInstalledAndAssociatedWithOrigin(app.id, frameUrl, p m)) {
89 installedApps.add(app); 123 installedApps.add(app);
90 } 124 }
91 } 125 }
92 126
93 RelatedApplication[] installedAppsArray = new RelatedApplication[install edApps.size()]; 127 RelatedApplication[] installedAppsArray = new RelatedApplication[install edApps.size()];
94 installedApps.toArray(installedAppsArray); 128 installedApps.toArray(installedAppsArray);
95 callback.call(installedAppsArray); 129 return installedAppsArray;
96 } 130 }
97 131
98 @Override
99 public void close() {}
100
101 @Override
102 public void onConnectionError(MojoException e) {}
103
104 /** 132 /**
105 * Determines whether a particular app is installed and matches the origin. 133 * Determines whether a particular app is installed and matches the origin.
106 * 134 *
107 * @param packageName Name of the Android package to check if installed. Ret urns false if the 135 * @param packageName Name of the Android package to check if installed. Ret urns false if the
108 * app is not installed. 136 * app is not installed.
109 * @param frameUrl Returns false if the Android package does not declare ass ociation with the 137 * @param frameUrl Returns false if the Android package does not declare ass ociation with the
110 * origin of this URL. Can be null. 138 * origin of this URL. Can be null.
111 */ 139 */
112 private static boolean isAppInstalledAndAssociatedWithOrigin( 140 private static boolean isAppInstalledAndAssociatedWithOrigin(
113 String packageName, URI frameUrl, PackageManager pm) { 141 String packageName, URI frameUrl, PackageManager pm) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 269
242 private static boolean statementTargetMatches(URI frameUrl, URI assetUrl) { 270 private static boolean statementTargetMatches(URI frameUrl, URI assetUrl) {
243 if (assetUrl.getScheme() == null || assetUrl.getAuthority() == null) { 271 if (assetUrl.getScheme() == null || assetUrl.getAuthority() == null) {
244 return false; 272 return false;
245 } 273 }
246 274
247 return assetUrl.getScheme().equals(frameUrl.getScheme()) 275 return assetUrl.getScheme().equals(frameUrl.getScheme())
248 && assetUrl.getAuthority().equals(frameUrl.getAuthority()); 276 && assetUrl.getAuthority().equals(frameUrl.getAuthority());
249 } 277 }
250 } 278 }
OLDNEW
« no previous file with comments | « no previous file | content/public/android/junit/src/org/chromium/content/browser/installedapp/InstalledAppProviderTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698