OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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.chrome.browser.externalnav; | 5 package org.chromium.chrome.browser.externalnav; |
6 | 6 |
7 import android.content.ActivityNotFoundException; | 7 import android.content.ActivityNotFoundException; |
8 import android.content.ComponentName; | 8 import android.content.ComponentName; |
9 import android.content.Intent; | 9 import android.content.Intent; |
10 import android.content.pm.ResolveInfo; | 10 import android.content.pm.ResolveInfo; |
(...skipping 10 matching lines...) Expand all Loading... | |
21 import org.chromium.chrome.browser.ChromeSwitches; | 21 import org.chromium.chrome.browser.ChromeSwitches; |
22 import org.chromium.chrome.browser.IntentHandler; | 22 import org.chromium.chrome.browser.IntentHandler; |
23 import org.chromium.chrome.browser.UrlConstants; | 23 import org.chromium.chrome.browser.UrlConstants; |
24 import org.chromium.chrome.browser.tab.Tab; | 24 import org.chromium.chrome.browser.tab.Tab; |
25 import org.chromium.chrome.browser.tab.TabRedirectHandler; | 25 import org.chromium.chrome.browser.tab.TabRedirectHandler; |
26 import org.chromium.chrome.browser.util.IntentUtils; | 26 import org.chromium.chrome.browser.util.IntentUtils; |
27 import org.chromium.chrome.browser.util.UrlUtilities; | 27 import org.chromium.chrome.browser.util.UrlUtilities; |
28 import org.chromium.ui.base.PageTransition; | 28 import org.chromium.ui.base.PageTransition; |
29 | 29 |
30 import java.net.URI; | 30 import java.net.URI; |
31 import java.util.Collections; | |
31 import java.util.HashSet; | 32 import java.util.HashSet; |
32 import java.util.List; | 33 import java.util.List; |
34 import java.util.Set; | |
33 import java.util.concurrent.TimeUnit; | 35 import java.util.concurrent.TimeUnit; |
34 | 36 |
35 /** | 37 /** |
36 * Logic related to the URL overriding/intercepting functionality. | 38 * Logic related to the URL overriding/intercepting functionality. |
37 * This feature allows Chrome to convert certain navigations to Android Intents allowing | 39 * This feature allows Chrome to convert certain navigations to Android Intents allowing |
38 * applications like Youtube to direct users clicking on a http(s) link to their native app. | 40 * applications like Youtube to direct users clicking on a http(s) link to their native app. |
39 */ | 41 */ |
40 public class ExternalNavigationHandler { | 42 public class ExternalNavigationHandler { |
41 private static final String TAG = "UrlHandler"; | 43 private static final String TAG = "UrlHandler"; |
42 private static final String SCHEME_WTAI = "wtai://wp/"; | 44 private static final String SCHEME_WTAI = "wtai://wp/"; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 boolean hasBrowserFallbackUrl = false; | 107 boolean hasBrowserFallbackUrl = false; |
106 String browserFallbackUrl = | 108 String browserFallbackUrl = |
107 IntentUtils.safeGetStringExtra(intent, EXTRA_BROWSER_FALLBACK_UR L); | 109 IntentUtils.safeGetStringExtra(intent, EXTRA_BROWSER_FALLBACK_UR L); |
108 if (browserFallbackUrl != null | 110 if (browserFallbackUrl != null |
109 && UrlUtilities.isValidForIntentFallbackNavigation(browserFallba ckUrl)) { | 111 && UrlUtilities.isValidForIntentFallbackNavigation(browserFallba ckUrl)) { |
110 hasBrowserFallbackUrl = true; | 112 hasBrowserFallbackUrl = true; |
111 } else { | 113 } else { |
112 browserFallbackUrl = null; | 114 browserFallbackUrl = null; |
113 } | 115 } |
114 | 116 |
117 if (!intentPackageSignatureMatches(intent)) { | |
118 return OverrideUrlLoadingResult.NO_OVERRIDE; | |
119 } | |
120 | |
115 long time = SystemClock.elapsedRealtime(); | 121 long time = SystemClock.elapsedRealtime(); |
116 OverrideUrlLoadingResult result = shouldOverrideUrlLoadingInternal( | 122 OverrideUrlLoadingResult result = shouldOverrideUrlLoadingInternal( |
117 params, intent, hasBrowserFallbackUrl, browserFallbackUrl); | 123 params, intent, hasBrowserFallbackUrl, browserFallbackUrl); |
118 RecordHistogram.recordTimesHistogram("Android.StrictMode.OverrideUrlLoad ingTime", | 124 RecordHistogram.recordTimesHistogram("Android.StrictMode.OverrideUrlLoad ingTime", |
119 SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECONDS); | 125 SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECONDS); |
120 | 126 |
121 if (result == OverrideUrlLoadingResult.NO_OVERRIDE && hasBrowserFallback Url | 127 if (result == OverrideUrlLoadingResult.NO_OVERRIDE && hasBrowserFallback Url |
122 && (params.getRedirectHandler() == null | 128 && (params.getRedirectHandler() == null |
123 // For instance, if this is a chained fallback URL, we i gnore it. | 129 // For instance, if this is a chained fallback URL, we i gnore it. |
124 || !params.getRedirectHandler().shouldNotOverrideUrlLoad ing())) { | 130 || !params.getRedirectHandler().shouldNotOverrideUrlLoad ing())) { |
125 return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, params); | 131 return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, params); |
126 } | 132 } |
127 return result; | 133 return result; |
128 } | 134 } |
129 | 135 |
136 /** | |
137 * When a custom scheme intent is trying to launch another application, veri fy the signature | |
138 * fingerprints of intent, if the fingerprint match fingerprints of target a pplication, the | |
139 * intent should override, or it shouldn't. | |
140 * | |
141 * @param intent intent from url. | |
142 * @return boolean, true if the feature is not supported or url should overr ide, | |
143 * false if the the intent should not override. | |
144 */ | |
please use gerrit instead
2016/08/01 21:05:24
/**
* Check if the signature specified in the int
| |
145 private boolean intentPackageSignatureMatches(Intent intent) { | |
146 //This feature is based on a custom scheme. Variable scheme is used to c heck whether | |
147 //the intent url has an extra custom scheme, if not, the feature won't w ork. | |
please use gerrit instead
2016/08/01 21:05:24
Add a space after "//".
| |
148 String scheme = intent.getData().getScheme(); | |
149 String fragment = intent.getData().getFragment(); | |
150 if (!TextUtils.isEmpty(scheme) && fragment != null && fragment.contains( ";")) { | |
151 String[] parts = fragment.split(";"); | |
152 Set<Set<String>> allFingerPrint256 = new HashSet<>(); | |
153 //Consider that apks may have same package name but different keysto res. | |
154 //1. An apk's signature may update and differ from old, so you may n eed config and | |
155 //support new and old signatures, but this is optional. (e.g. (1)onl y config new | |
156 //fingerprint. (2)only config old fingerprint.(3)config new and old fingerprint) | |
157 //2. An apk itself may contain more than one keystore to sign. | |
158 //e.g.suppose apk's new signatures are sha256_1 and sha256_2, old si gnature | |
159 //is sha256_3. You can config the intent like "...;sha256=sha256_1,s ha256_2;..." | |
160 //or "...;sha256=sha256_1,sha256_2|sha256_3;..." | |
please use gerrit instead
2016/08/01 21:05:24
Add a space after "//".
| |
161 String pkgName = ""; | |
162 String fingerPrint256 = ""; | |
163 String[] fingerPrint256DifGroups; | |
164 for (int i = 0; i < parts.length; ++i) { | |
165 String[] part = parts[i].split("="); | |
166 if (part.length < 2) { | |
167 return false; | |
168 } | |
169 if (part[0].equals("sha256")) { | |
170 fingerPrint256 = part[1]; | |
171 } | |
172 if (part[0].equals("package")) { | |
173 pkgName = part[1]; | |
174 } | |
175 } | |
176 if (!TextUtils.isEmpty(pkgName) && !TextUtils.isEmpty(fingerPrint256 )) { | |
177 fingerPrint256DifGroups = fingerPrint256.split("\\|"); | |
178 for (int i = 0; i < fingerPrint256DifGroups.length; ++i) { | |
179 Set<String> fingerPrint256GroupSignKeySet = new HashSet<>(); | |
180 Collections.addAll(fingerPrint256GroupSignKeySet, fingerPrin t256DifGroups[i] | |
181 .split(",")); | |
182 allFingerPrint256.add(fingerPrint256GroupSignKeySet); | |
183 } | |
184 Set<String> fingerPrint256Set = mDelegate.getPackageSHA256Finger prints(pkgName); | |
185 if (fingerPrint256Set == null || !allFingerPrint256.contains(fin gerPrint256Set)) { | |
186 return false; | |
187 } | |
188 } | |
189 } | |
190 return true; | |
191 } | |
192 | |
130 private boolean resolversSubsetOf(List<ResolveInfo> infos, List<ResolveInfo> container) { | 193 private boolean resolversSubsetOf(List<ResolveInfo> infos, List<ResolveInfo> container) { |
131 HashSet<ComponentName> containerSet = new HashSet<>(); | 194 HashSet<ComponentName> containerSet = new HashSet<>(); |
132 for (ResolveInfo info : container) { | 195 for (ResolveInfo info : container) { |
133 containerSet.add( | 196 containerSet.add( |
134 new ComponentName(info.activityInfo.packageName, info.activi tyInfo.name)); | 197 new ComponentName(info.activityInfo.packageName, info.activi tyInfo.name)); |
135 } | 198 } |
136 for (ResolveInfo info : infos) { | 199 for (ResolveInfo info : infos) { |
137 if (!containerSet.contains(new ComponentName( | 200 if (!containerSet.contains(new ComponentName( |
138 info.activityInfo.packageName, info.activityInfo.name))) { | 201 info.activityInfo.packageName, info.activityInfo.name))) { |
139 return false; | 202 return false; |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
514 if (defaultSmsPackageName == null) return null; | 577 if (defaultSmsPackageName == null) return null; |
515 // Makes sure that the default SMS app actually resolves the intent. | 578 // Makes sure that the default SMS app actually resolves the intent. |
516 for (ResolveInfo resolveInfo : resolvingComponentNames) { | 579 for (ResolveInfo resolveInfo : resolvingComponentNames) { |
517 if (defaultSmsPackageName.equals(resolveInfo.activityInfo.packageNam e)) { | 580 if (defaultSmsPackageName.equals(resolveInfo.activityInfo.packageNam e)) { |
518 return defaultSmsPackageName; | 581 return defaultSmsPackageName; |
519 } | 582 } |
520 } | 583 } |
521 return null; | 584 return null; |
522 } | 585 } |
523 } | 586 } |
OLD | NEW |