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

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

Issue 1756793004: Chrome-side patch for IsAppInstalled. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@splitpatch2
Patch Set: Created 4 years, 9 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 2016 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.content.browser.installedapp;
6
7 import android.content.Context;
8 import android.content.pm.PackageManager;
9 import android.content.pm.PackageManager.NameNotFoundException;
10 import android.content.res.Resources;
11
12 import org.chromium.mojo.system.MojoException;
13 import org.chromium.mojom.content.InstalledAppProvider;
14 import org.chromium.mojom.content.RelatedApplication;
15
16 import org.json.JSONException;
17 import org.json.JSONObject;
18
19 import java.net.MalformedURLException;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.List;
25
26 /**
27 * Android implementation of the InstalledAppProvider service defined in
28 * content/common/installedapp/installed_app_provider.mojom.
29 */
30 public class InstalledAppProviderImpl implements InstalledAppProvider {
31 private Context mContext;
32 private static final String ASSET_DESCRIPTOR_FIELD_TARGET = "target";
33 private static final String ASSET_DESCRIPTOR_WEB = "web";
34 private static final String ASSET_DESCRIPTOR_FIELD_SITE = "site";
35 private static final String ASSET_DESCRIPTOR_FIELD_NAMESPACE = "namespace";
36 private static final String ASSOCIATED_ASSETS_KEY = "associated_assets";
37 private static final String RELATED_APP_ANDROID_PLATFORM = "play";
38
39 public InstalledAppProviderImpl(Context context) {
40 mContext = context;
41 }
42
43 @Override
44 public void filterInstalledApps(
45 RelatedApplication[] apps, String origin, FilterInstalledAppsRespons e callback) {
46 callback.call(filterAndroidInstalledApps(apps, origin));
47 }
48
49 public RelatedApplication[] filterAndroidInstalledApps(
50 RelatedApplication[] apps, String origin) {
51 ArrayList<RelatedApplication> installedApps = new ArrayList<RelatedAppli cation>();
52 PackageManager pm = mContext.getPackageManager();
53 for (RelatedApplication app : apps) {
54 // If the package is of type "play" and origin is associated with pa ckage,
55 // add the package to the list of valid packages.
56 if (app.platform.equals(RELATED_APP_ANDROID_PLATFORM)
57 && isOriginAssociatedWithPackage(app.id, origin, pm)) {
58 installedApps.add(app);
59 }
60 }
61 RelatedApplication installedAppsArray[] = new RelatedApplication[install edApps.size()];
62 installedAppsArray = installedApps.toArray(installedAppsArray);
63 return installedAppsArray;
64 }
65
66 @Override
67 public void close() {}
68
69 @Override
70 public void onConnectionError(MojoException e) {}
71
72 private static List<String> getAssociations(String packageName, PackageManag er pm) {
73 Resources resources;
74
75 try {
76 resources = pm.getResourcesForApplication(packageName);
77 } catch (NameNotFoundException e) {
78 return Collections.<String>emptyList();
79 }
80
81 if (resources == null) {
82 return Collections.<String>emptyList();
83 }
84
85 int identifier = resources.getIdentifier(ASSOCIATED_ASSETS_KEY, "array", packageName);
86 if (identifier == 0) {
87 return Collections.<String>emptyList();
88 }
89 return Arrays.asList(resources.getStringArray(identifier));
90 }
91
92 private static boolean isOriginAssociatedWithPackage(
93 String packageName, String origin, PackageManager pm) {
94 List<String> associations = getAssociations(packageName, pm);
95 URL originURL;
96 try {
97 originURL = new URL(origin);
98 } catch (MalformedURLException e) {
99 return false;
100 }
101
102 for (String statementString : associations) {
103 try {
104 JSONObject statement = new JSONObject(statementString);
105 String assetDescriptorJson = statement.getString(ASSET_DESCRIPTO R_FIELD_TARGET);
106 JSONObject assetJson = new JSONObject(assetDescriptorJson);
107
108 // If it is not a web appet, skip it.
109 if (!isAssetIsWeb(assetJson)) {
110 continue;
111 }
112
113 URL assetURL;
114 try {
115 assetURL = new URL(assetJson.getString(ASSET_DESCRIPTOR_FIEL D_SITE));
116 } catch (MalformedURLException e) {
117 continue;
118 }
119
120 // The URL is considered equivalent if the scheme, host, and por t match, according
121 // to the DigitalAssetLinks v1 spec.
122 if (statementTargetMatches(originURL, assetURL)) {
123 return true;
124 }
125 } catch (JSONException e) {
126 continue;
127 }
128 }
129
130 return false;
131 }
132
133 private static boolean isAssetIsWeb(JSONObject asset) {
134 try {
135 return asset.getString(ASSET_DESCRIPTOR_FIELD_NAMESPACE).equals(ASSE T_DESCRIPTOR_WEB);
136 } catch (JSONException e) {
137 return false;
138 }
139 }
140
141 private static boolean statementTargetMatches(URL originURL, URL assetURL) {
142 return (assetURL.getProtocol().equals(originURL.getProtocol())
143 && assetURL.getHost().equals(originURL.getHost())
144 && assetURL.getPort() == originURL.getPort());
145 }
146 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698