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.Manifest.permission; | 7 import android.Manifest.permission; |
8 import android.app.Activity; | 8 import android.app.Activity; |
9 import android.content.ComponentName; | 9 import android.content.ComponentName; |
10 import android.content.Context; | 10 import android.content.Context; |
(...skipping 23 matching lines...) Expand all Loading... | |
34 import org.chromium.chrome.browser.IntentHandler; | 34 import org.chromium.chrome.browser.IntentHandler; |
35 import org.chromium.chrome.browser.document.ChromeLauncherActivity; | 35 import org.chromium.chrome.browser.document.ChromeLauncherActivity; |
36 import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler.Overrid eUrlLoadingResult; | 36 import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler.Overrid eUrlLoadingResult; |
37 import org.chromium.chrome.browser.tab.Tab; | 37 import org.chromium.chrome.browser.tab.Tab; |
38 import org.chromium.chrome.browser.util.FeatureUtilities; | 38 import org.chromium.chrome.browser.util.FeatureUtilities; |
39 import org.chromium.chrome.browser.util.IntentUtils; | 39 import org.chromium.chrome.browser.util.IntentUtils; |
40 import org.chromium.chrome.browser.util.UrlUtilities; | 40 import org.chromium.chrome.browser.util.UrlUtilities; |
41 import org.chromium.content_public.browser.LoadUrlParams; | 41 import org.chromium.content_public.browser.LoadUrlParams; |
42 import org.chromium.content_public.common.Referrer; | 42 import org.chromium.content_public.common.Referrer; |
43 import org.chromium.ui.base.PageTransition; | 43 import org.chromium.ui.base.PageTransition; |
44 import org.chromium.ui.base.WindowAndroid; | |
44 import org.chromium.ui.base.WindowAndroid.PermissionCallback; | 45 import org.chromium.ui.base.WindowAndroid.PermissionCallback; |
45 | 46 |
46 import java.util.List; | 47 import java.util.List; |
47 | 48 |
48 /** | 49 /** |
49 * The main implementation of the {@link ExternalNavigationDelegate}. | 50 * The main implementation of the {@link ExternalNavigationDelegate}. |
50 */ | 51 */ |
51 public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat e { | 52 public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat e { |
52 private static final String TAG = "ExternalNavigationDelegateImpl"; | 53 private static final String TAG = "ExternalNavigationDelegateImpl"; |
53 private static final String PDF_VIEWER = "com.google.android.apps.docs"; | 54 private static final String PDF_VIEWER = "com.google.android.apps.docs"; |
54 private static final String PDF_MIME = "application/pdf"; | 55 private static final String PDF_MIME = "application/pdf"; |
55 private static final String PDF_SUFFIX = ".pdf"; | 56 private static final String PDF_SUFFIX = ".pdf"; |
56 private final ChromeActivity mActivity; | 57 private final Tab mTab; |
58 protected final Context mApplicationContext; | |
57 | 59 |
58 public ExternalNavigationDelegateImpl(ChromeActivity activity) { | 60 public ExternalNavigationDelegateImpl(Tab tab) { |
59 mActivity = activity; | 61 mTab = tab; |
62 // At the point of creation the tab should have a valid WindowAndroid. | |
gone
2016/01/25 23:42:43
Add an assert?
Yusuf
2016/01/25 23:55:59
Done.
| |
63 mApplicationContext = tab.getWindowAndroid().getContext().get().getAppli cationContext(); | |
60 } | 64 } |
61 | 65 |
62 /** | 66 /** |
63 * @return The activity that this delegate is associated with. | 67 * @return The activity {@link Context} if it can be reached. |
gone
2016/01/25 23:42:43
nit: Explicitly specify when you'd need this funct
Yusuf
2016/01/25 23:55:59
Done.
| |
68 * Application {@link Context} if not. | |
64 */ | 69 */ |
65 protected final Activity getActivity() { | 70 protected final Context getActivityContextIfAvailable() { |
66 return mActivity; | 71 if (mTab.getWindowAndroid() == null) return mApplicationContext; |
72 Context activityContext = WindowAndroid.activityFromContext( | |
73 mTab.getWindowAndroid().getContext().get()); | |
74 if (activityContext == null) return mApplicationContext; | |
75 return activityContext; | |
67 } | 76 } |
68 | 77 |
69 /** | 78 /** |
70 * If the intent is for a pdf, resolves intent handlers to find the platform pdf viewer if | 79 * If the intent is for a pdf, resolves intent handlers to find the platform pdf viewer if |
71 * it is available and force is for the provided |intent| so that the user d oesn't need to | 80 * it is available and force is for the provided |intent| so that the user d oesn't need to |
72 * choose it from Intent picker. | 81 * choose it from Intent picker. |
73 * | 82 * |
74 * @param context Context of the app. | 83 * @param context Context of the app. |
75 * @param intent Intent to open. | 84 * @param intent Intent to open. |
76 */ | 85 */ |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 return info != null | 191 return info != null |
183 && info.activityInfo.packageName.equals(context.getPackageNa me()); | 192 && info.activityInfo.packageName.equals(context.getPackageNa me()); |
184 } catch (RuntimeException e) { | 193 } catch (RuntimeException e) { |
185 logTransactionTooLargeOrRethrow(e, intent); | 194 logTransactionTooLargeOrRethrow(e, intent); |
186 return false; | 195 return false; |
187 } | 196 } |
188 } | 197 } |
189 | 198 |
190 @Override | 199 @Override |
191 public List<ComponentName> queryIntentActivities(Intent intent) { | 200 public List<ComponentName> queryIntentActivities(Intent intent) { |
192 return IntentUtils.getIntentHandlers(mActivity, intent); | 201 return IntentUtils.getIntentHandlers(mApplicationContext, intent); |
193 } | 202 } |
194 | 203 |
195 @Override | 204 @Override |
196 public boolean willChromeHandleIntent(Intent intent) { | 205 public boolean willChromeHandleIntent(Intent intent) { |
197 return willChromeHandleIntent(mActivity, intent, false); | 206 return willChromeHandleIntent(mApplicationContext, intent, false); |
198 } | 207 } |
199 | 208 |
200 @Override | 209 @Override |
201 public boolean isSpecializedHandlerAvailable(Intent intent) { | 210 public boolean isSpecializedHandlerAvailable(Intent intent) { |
202 return isPackageSpecializedHandler(mActivity, null, intent); | 211 return isPackageSpecializedHandler(mApplicationContext, null, intent); |
203 } | 212 } |
204 | 213 |
205 /** | 214 /** |
206 * Check whether the given package is a specialized handler for the given in tent | 215 * Check whether the given package is a specialized handler for the given in tent |
207 * | 216 * |
208 * @param context {@link Context} to use for getting the {@link PackageManag er}. | 217 * @param context {@link Context} to use for getting the {@link PackageManag er}. |
209 * @param packageName Package name to check against. Can be null or empty. | 218 * @param packageName Package name to check against. Can be null or empty. |
210 * @param intent The intent to resolve for. | 219 * @param intent The intent to resolve for. |
211 * @return Whether the given package is a specialized handler for the given intent. If there is | 220 * @return Whether the given package is a specialized handler for the given intent. If there is |
212 * no package name given checks whether there is any specialized han dler. | 221 * no package name given checks whether there is any specialized han dler. |
(...skipping 22 matching lines...) Expand all Loading... | |
235 return true; | 244 return true; |
236 } | 245 } |
237 } catch (RuntimeException e) { | 246 } catch (RuntimeException e) { |
238 logTransactionTooLargeOrRethrow(e, intent); | 247 logTransactionTooLargeOrRethrow(e, intent); |
239 } | 248 } |
240 return false; | 249 return false; |
241 } | 250 } |
242 | 251 |
243 @Override | 252 @Override |
244 public String getPackageName() { | 253 public String getPackageName() { |
245 return mActivity.getPackageName(); | 254 return mApplicationContext.getPackageName(); |
246 } | 255 } |
247 | 256 |
248 @Override | 257 @Override |
249 public void startActivity(Intent intent) { | 258 public void startActivity(Intent intent) { |
250 try { | 259 try { |
251 forcePdfViewerAsIntentHandlerIfNeeded(mActivity, intent); | 260 forcePdfViewerAsIntentHandlerIfNeeded(mApplicationContext, intent); |
252 mActivity.startActivity(intent); | 261 Context context = getActivityContextIfAvailable(); |
262 if (!(context instanceof Activity)) intent.addFlags(Intent.FLAG_ACTI VITY_NEW_TASK); | |
263 context.startActivity(intent); | |
253 } catch (RuntimeException e) { | 264 } catch (RuntimeException e) { |
254 logTransactionTooLargeOrRethrow(e, intent); | 265 logTransactionTooLargeOrRethrow(e, intent); |
255 } | 266 } |
256 } | 267 } |
257 | 268 |
258 @Override | 269 @Override |
259 public boolean startActivityIfNeeded(Intent intent) { | 270 public boolean startActivityIfNeeded(Intent intent) { |
260 try { | 271 try { |
261 forcePdfViewerAsIntentHandlerIfNeeded(mActivity, intent); | 272 forcePdfViewerAsIntentHandlerIfNeeded(mApplicationContext, intent); |
262 return mActivity.startActivityIfNeeded(intent, -1); | 273 Context context = getActivityContextIfAvailable(); |
274 if (!(context instanceof Activity)) return false; | |
275 return ((Activity) context).startActivityIfNeeded(intent, -1); | |
gone
2016/01/25 23:42:43
if (context instanceof Activity) {
return ((Ac
Yusuf
2016/01/25 23:55:59
Done.
| |
263 } catch (RuntimeException e) { | 276 } catch (RuntimeException e) { |
264 logTransactionTooLargeOrRethrow(e, intent); | 277 logTransactionTooLargeOrRethrow(e, intent); |
265 return false; | 278 return false; |
266 } | 279 } |
267 } | 280 } |
268 | 281 |
269 @Override | 282 @Override |
270 public void startIncognitoIntent(final Intent intent, final String referrerU rl, | 283 public void startIncognitoIntent(final Intent intent, final String referrerU rl, |
271 final String fallbackUrl, final Tab tab, final boolean needsToCloseT ab) { | 284 final String fallbackUrl, final Tab tab, final boolean needsToCloseT ab) { |
272 new AlertDialog.Builder(mActivity, R.style.AlertDialogTheme) | 285 Context context = tab.getWindowAndroid().getContext().get(); |
286 if (!(context instanceof Activity)) return; | |
gone
2016/01/25 23:42:43
nit newline
Yusuf
2016/01/25 23:55:59
Done.
| |
287 Activity activity = (Activity) context; | |
288 new AlertDialog.Builder(activity, R.style.AlertDialogTheme) | |
273 .setTitle(R.string.external_app_leave_incognito_warning_title) | 289 .setTitle(R.string.external_app_leave_incognito_warning_title) |
274 .setMessage(R.string.external_app_leave_incognito_warning) | 290 .setMessage(R.string.external_app_leave_incognito_warning) |
275 .setPositiveButton(R.string.ok, new OnClickListener() { | 291 .setPositiveButton(R.string.ok, new OnClickListener() { |
276 @Override | 292 @Override |
277 public void onClick(DialogInterface dialog, int which) { | 293 public void onClick(DialogInterface dialog, int which) { |
278 startActivity(intent); | 294 startActivity(intent); |
279 if (tab != null && !tab.isClosing() && tab.isInitialized () | 295 if (tab != null && !tab.isClosing() && tab.isInitialized () |
280 && needsToCloseTab) { | 296 && needsToCloseTab) { |
281 closeTab(tab); | 297 closeTab(tab); |
282 } | 298 } |
(...skipping 14 matching lines...) Expand all Loading... | |
297 .show(); | 313 .show(); |
298 } | 314 } |
299 | 315 |
300 @Override | 316 @Override |
301 public boolean shouldRequestFileAccess(String url, Tab tab) { | 317 public boolean shouldRequestFileAccess(String url, Tab tab) { |
302 // If the tab is null, then do not attempt to prompt for access. | 318 // If the tab is null, then do not attempt to prompt for access. |
303 if (tab == null) return false; | 319 if (tab == null) return false; |
304 | 320 |
305 // If the url points inside of Chromium's data directory, no permissions are necessary. | 321 // If the url points inside of Chromium's data directory, no permissions are necessary. |
306 // This is required to prevent permission prompt when uses wants to acce ss offline pages. | 322 // This is required to prevent permission prompt when uses wants to acce ss offline pages. |
307 if (url.startsWith("file://" + PathUtils.getDataDirectory( | 323 if (url.startsWith("file://" + PathUtils.getDataDirectory(mApplicationCo ntext))) { |
308 mActivity.getApplicationContext()))) { | |
309 return false; | 324 return false; |
310 } | 325 } |
311 | 326 |
312 return !tab.getWindowAndroid().hasPermission(permission.WRITE_EXTERNAL_S TORAGE) | 327 return !tab.getWindowAndroid().hasPermission(permission.WRITE_EXTERNAL_S TORAGE) |
313 && tab.getWindowAndroid().canRequestPermission(permission.WRITE_ EXTERNAL_STORAGE); | 328 && tab.getWindowAndroid().canRequestPermission(permission.WRITE_ EXTERNAL_STORAGE); |
314 } | 329 } |
315 | 330 |
316 @Override | 331 @Override |
317 public void startFileIntent(final Intent intent, final String referrerUrl, f inal Tab tab, | 332 public void startFileIntent(final Intent intent, final String referrerUrl, f inal Tab tab, |
318 final boolean needsToCloseTab) { | 333 final boolean needsToCloseTab) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 return; | 367 return; |
353 } | 368 } |
354 | 369 |
355 if (needsToStartIntent) { | 370 if (needsToStartIntent) { |
356 intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | 371 intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); |
357 intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName()); | 372 intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName()); |
358 if (launchIncogntio) intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_IN COGNITO_TAB, true); | 373 if (launchIncogntio) intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_IN COGNITO_TAB, true); |
359 intent.addCategory(Intent.CATEGORY_BROWSABLE); | 374 intent.addCategory(Intent.CATEGORY_BROWSABLE); |
360 intent.setClassName(getPackageName(), ChromeLauncherActivity.class.g etName()); | 375 intent.setClassName(getPackageName(), ChromeLauncherActivity.class.g etName()); |
361 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 376 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
362 IntentHandler.addTrustedIntentExtras(intent, mActivity); | 377 IntentHandler.addTrustedIntentExtras(intent, mApplicationContext); |
363 startActivity(intent); | 378 startActivity(intent); |
364 | 379 |
365 if (needsToCloseTab) closeTab(tab); | 380 if (needsToCloseTab) closeTab(tab); |
366 return; | 381 return; |
367 } | 382 } |
368 | 383 |
369 LoadUrlParams loadUrlParams = new LoadUrlParams(url, PageTransition.AUTO _TOPLEVEL); | 384 LoadUrlParams loadUrlParams = new LoadUrlParams(url, PageTransition.AUTO _TOPLEVEL); |
370 if (!TextUtils.isEmpty(referrerUrl)) { | 385 if (!TextUtils.isEmpty(referrerUrl)) { |
371 Referrer referrer = new Referrer(referrerUrl, Referrer.REFERRER_POLI CY_ALWAYS); | 386 Referrer referrer = new Referrer(referrerUrl, Referrer.REFERRER_POLI CY_ALWAYS); |
372 loadUrlParams.setReferrer(referrer); | 387 loadUrlParams.setReferrer(referrer); |
(...skipping 26 matching lines...) Expand all Loading... | |
399 } | 414 } |
400 | 415 |
401 @Override | 416 @Override |
402 public boolean isChromeAppInForeground() { | 417 public boolean isChromeAppInForeground() { |
403 return ApplicationStatus.getStateForApplication() | 418 return ApplicationStatus.getStateForApplication() |
404 == ApplicationState.HAS_RUNNING_ACTIVITIES; | 419 == ApplicationState.HAS_RUNNING_ACTIVITIES; |
405 } | 420 } |
406 | 421 |
407 @Override | 422 @Override |
408 public boolean isDocumentMode() { | 423 public boolean isDocumentMode() { |
409 return FeatureUtilities.isDocumentMode(mActivity); | 424 return FeatureUtilities.isDocumentMode(mApplicationContext); |
410 } | 425 } |
411 | 426 |
412 @Override | 427 @Override |
413 public String getDefaultSmsPackageName() { | 428 public String getDefaultSmsPackageName() { |
414 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return null; | 429 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return null; |
415 return Telephony.Sms.getDefaultSmsPackage(mActivity); | 430 return Telephony.Sms.getDefaultSmsPackage(mApplicationContext); |
416 } | 431 } |
417 | 432 |
418 private static void logTransactionTooLargeOrRethrow(RuntimeException e, Inte nt intent) { | 433 private static void logTransactionTooLargeOrRethrow(RuntimeException e, Inte nt intent) { |
419 // See http://crbug.com/369574. | 434 // See http://crbug.com/369574. |
420 if (e.getCause() instanceof TransactionTooLargeException) { | 435 if (e.getCause() instanceof TransactionTooLargeException) { |
421 Log.e(TAG, "Could not resolve Activity for intent " + intent.toStrin g(), e); | 436 Log.e(TAG, "Could not resolve Activity for intent " + intent.toStrin g(), e); |
422 } else { | 437 } else { |
423 throw e; | 438 throw e; |
424 } | 439 } |
425 } | 440 } |
426 | 441 |
427 private void closeTab(Tab tab) { | 442 private void closeTab(Tab tab) { |
428 mActivity.getTabModelSelector().closeTab(tab); | 443 Context context = tab.getWindowAndroid().getContext().get(); |
444 if (!(context instanceof ChromeActivity)) return; | |
gone
2016/01/25 23:42:43
if (context instanceof ChromeActivity) {
((Chr
Yusuf
2016/01/25 23:55:59
Done.
| |
445 ((ChromeActivity) context).getTabModelSelector().closeTab(tab); | |
429 } | 446 } |
430 } | 447 } |
OLD | NEW |