OLD | NEW |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |