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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java

Issue 2568843003: Allow deferred intent when the screen is locked (Closed)
Patch Set: Allow deferred intent when the screen is locked Created 4 years 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
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; 5 package org.chromium.chrome.browser;
6 6
7 import android.app.KeyguardManager; 7 import android.app.KeyguardManager;
8 import android.app.PendingIntent; 8 import android.app.PendingIntent;
9 import android.app.SearchManager; 9 import android.app.SearchManager;
10 import android.content.ComponentName; 10 import android.content.ComponentName;
11 import android.content.Context; 11 import android.content.Context;
12 import android.content.Intent; 12 import android.content.Intent;
13 import android.content.IntentFilter;
13 import android.net.Uri; 14 import android.net.Uri;
14 import android.os.Bundle; 15 import android.os.Bundle;
15 import android.os.SystemClock; 16 import android.os.SystemClock;
16 import android.provider.Browser; 17 import android.provider.Browser;
17 import android.provider.MediaStore; 18 import android.provider.MediaStore;
18 import android.speech.RecognizerResultsIntent; 19 import android.speech.RecognizerResultsIntent;
19 import android.text.TextUtils; 20 import android.text.TextUtils;
20 import android.util.Pair; 21 import android.util.Pair;
21 22
22 import org.chromium.base.ApiCompatibilityUtils; 23 import org.chromium.base.ApiCompatibilityUtils;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 // publicly available. 220 // publicly available.
220 private static final String TAB_ACTIVITY_COMPONENT_CLASS_NAME = 221 private static final String TAB_ACTIVITY_COMPONENT_CLASS_NAME =
221 "com.google.android.apps.chrome.Main"; 222 "com.google.android.apps.chrome.Main";
222 223
223 private static boolean sTestIntentsEnabled; 224 private static boolean sTestIntentsEnabled;
224 225
225 private final IntentHandlerDelegate mDelegate; 226 private final IntentHandlerDelegate mDelegate;
226 private final String mPackageName; 227 private final String mPackageName;
227 private KeyguardManager mKeyguardManager; 228 private KeyguardManager mKeyguardManager;
228 229
230 /**
231 * Receiver for screen unlock broadcast.
232 */
233 private KeyguardBroadcastReceiver mKeyguardBroadcastReceiver;
234
229 public static enum TabOpenType { 235 public static enum TabOpenType {
230 OPEN_NEW_TAB, 236 OPEN_NEW_TAB,
231 // Tab is reused only if the URLs perfectly match. 237 // Tab is reused only if the URLs perfectly match.
232 REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, 238 REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB,
233 // Tab is reused only if there's an existing tab opened by the same app ID. 239 // Tab is reused only if there's an existing tab opened by the same app ID.
234 REUSE_APP_ID_MATCHING_TAB_ELSE_NEW_TAB, 240 REUSE_APP_ID_MATCHING_TAB_ELSE_NEW_TAB,
235 CLOBBER_CURRENT_TAB, 241 CLOBBER_CURRENT_TAB,
236 BRING_TAB_TO_FRONT, 242 BRING_TAB_TO_FRONT,
237 // Opens a new incognito tab. 243 // Opens a new incognito tab.
238 OPEN_NEW_INCOGNITO_TAB, 244 OPEN_NEW_INCOGNITO_TAB,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 List<String> packages = IntentUtils.safeGetStringArrayListExtra(intent, 330 List<String> packages = IntentUtils.safeGetStringArrayListExtra(intent,
325 IntentHandler.EXTRA_EXTERNAL_NAV_PACKAGES); 331 IntentHandler.EXTRA_EXTERNAL_NAV_PACKAGES);
326 if (packages != null && packages.size() > 0) { 332 if (packages != null && packages.size() > 0) {
327 RecordUserAction.record("MobileExternalNavigationReceived"); 333 RecordUserAction.record("MobileExternalNavigationReceived");
328 for (String name : packages) { 334 for (String name : packages) {
329 RapporServiceBridge.sampleString("Android.ExternalNavigationNotC hosen", name); 335 RapporServiceBridge.sampleString("Android.ExternalNavigationNotC hosen", name);
330 } 336 }
331 } 337 }
332 } 338 }
333 339
340 @VisibleForTesting
341 void tryUnregisterLockscreenIntentReceiver(Context context, Intent intent) {
342 // Only unregister receiver when the intent was specially marked or the receiver no longer
343 // contain any valid deferred intent.
344 // If the intent does not contain the special mark, it should be treated as normal intent
345 // instead. This is helping the scenario when the screen is unlocked, an other intent is
346 // fired before the broadcast.
Maria 2016/12/13 21:36:09 I think that if another event was fired before the
Sherry 2016/12/13 22:13:54 If the deferred intent is still within the lifetim
Sherry 2016/12/13 22:32:29 My bad, you are right. If the new irrelevant inten
Ted C 2016/12/13 22:47:13 I agree with Maria. If another intent was receive
347 if (mKeyguardBroadcastReceiver != null
348 && !mKeyguardBroadcastReceiver.hasValidDeferredIntent(intent)) {
349 context.unregisterReceiver(mKeyguardBroadcastReceiver);
350 mKeyguardBroadcastReceiver = null;
351 }
352 }
353
334 /** 354 /**
335 * Handles an Intent after the ChromeTabbedActivity decides that it shouldn' t ignore the 355 * Handles an Intent after the ChromeTabbedActivity decides that it shouldn' t ignore the
336 * Intent. 356 * Intent.
337 * 357 * @param context Android Context.
358 * @param intent Target intent.
338 * @return Whether the Intent was successfully handled. 359 * @return Whether the Intent was successfully handled.
339 */ 360 */
340 boolean onNewIntent(Context context, Intent intent) { 361 boolean onNewIntent(Context context, Intent intent) {
362 tryUnregisterLockscreenIntentReceiver(context, intent);
363
341 assert intentHasValidUrl(intent); 364 assert intentHasValidUrl(intent);
342 String url = getUrlFromIntent(intent); 365 String url = getUrlFromIntent(intent);
343 boolean hasUserGesture = 366 boolean hasUserGesture =
344 IntentWithGesturesHandler.getInstance().getUserGestureAndClear(i ntent); 367 IntentWithGesturesHandler.getInstance().getUserGestureAndClear(i ntent);
345 TabOpenType tabOpenType = getTabOpenType(intent); 368 TabOpenType tabOpenType = getTabOpenType(intent);
346 int tabIdToBringToFront = IntentUtils.safeGetIntExtra( 369 int tabIdToBringToFront = IntentUtils.safeGetIntExtra(
347 intent, TabOpenType.BRING_TAB_TO_FRONT.name(), Tab.INVALID_TAB_I D); 370 intent, TabOpenType.BRING_TAB_TO_FRONT.name(), Tab.INVALID_TAB_I D);
348 if (url == null && tabIdToBringToFront == Tab.INVALID_TAB_ID 371 if (url == null && tabIdToBringToFront == Tab.INVALID_TAB_ID
349 && tabOpenType != TabOpenType.OPEN_NEW_INCOGNITO_TAB) { 372 && tabOpenType != TabOpenType.OPEN_NEW_INCOGNITO_TAB) {
350 return handleWebSearchIntent(intent); 373 return handleWebSearchIntent(intent);
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 } 704 }
682 705
683 Log.w(TAG, "Ignoring internal Chrome URL from untrustworthy source."); 706 Log.w(TAG, "Ignoring internal Chrome URL from untrustworthy source.");
684 return true; 707 return true;
685 } 708 }
686 } 709 }
687 710
688 // We must check for screen state at this point. 711 // We must check for screen state at this point.
689 // These might be slow. 712 // These might be slow.
690 boolean internalOrVisible = isInternal || isIntentUserVisible(contex t); 713 boolean internalOrVisible = isInternal || isIntentUserVisible(contex t);
691 return !internalOrVisible; 714 if (!internalOrVisible) {
715 // Register keyguard broadcast receiver to receive ACTION_USER_P RESENT when the
716 // screen is unlocked.
717 // Avoid register KeyguardBroadcastReceiver if there is already one cached to allow
718 // unregister on the same instance.
719 // The ACTION_USER_PRESENT is sent by platform to indicates when user is present.
720 if (mKeyguardBroadcastReceiver == null) {
721 mKeyguardBroadcastReceiver = new KeyguardBroadcastReceiver(i ntent);
722 context.registerReceiver(mKeyguardBroadcastReceiver,
723 new IntentFilter(Intent.ACTION_USER_PRESENT));
724 } else {
725 mKeyguardBroadcastReceiver.updateDeferredIntent(intent);
726 }
Maria 2016/12/13 21:36:09 maybe move these lines into a method registerLocks
Sherry 2016/12/13 22:13:54 Sounds good to me. Will update.
Ted C 2016/12/13 22:47:13 Also, I would have the receiver unregister itself
Sherry 2016/12/14 00:54:07 Then we need a background task that continuously c
727 return true;
728 }
729 return false;
692 } catch (Throwable t) { 730 } catch (Throwable t) {
693 return true; 731 return true;
694 } 732 }
695 } 733 }
696 734
697 @VisibleForTesting 735 @VisibleForTesting
736 void setKeyguardBroadcastReceiverForTesting(KeyguardBroadcastReceiver receiv er) {
737 mKeyguardBroadcastReceiver = receiver;
738 }
739
740 @VisibleForTesting
698 boolean intentHasValidUrl(Intent intent) { 741 boolean intentHasValidUrl(Intent intent) {
699 String url = getUrlFromIntent(intent); 742 String url = getUrlFromIntent(intent);
700 743
701 // Always drop insecure urls. 744 // Always drop insecure urls.
702 if (url != null && isJavascriptSchemeOrInvalidUrl(url)) { 745 if (url != null && isJavascriptSchemeOrInvalidUrl(url)) {
703 return false; 746 return false;
704 } 747 }
705 return true; 748 return true;
706 } 749 }
707 750
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 if (isChromeToken(token, context)) { 797 if (isChromeToken(token, context)) {
755 return true; 798 return true;
756 } 799 }
757 if (ExternalAuthUtils.getInstance().isGoogleSigned( 800 if (ExternalAuthUtils.getInstance().isGoogleSigned(
758 context, ApiCompatibilityUtils.getCreatorPackage(token))) { 801 context, ApiCompatibilityUtils.getCreatorPackage(token))) {
759 return true; 802 return true;
760 } 803 }
761 return false; 804 return false;
762 } 805 }
763 806
764 private boolean isIntentUserVisible(Context context) { 807 @VisibleForTesting
808 boolean isIntentUserVisible(Context context) {
765 // Only process Intents if the screen is on and the device is unlocked; 809 // Only process Intents if the screen is on and the device is unlocked;
766 // i.e. the user will see what is going on. 810 // i.e. the user will see what is going on.
767 if (mKeyguardManager == null) { 811 if (mKeyguardManager == null) {
768 mKeyguardManager = (KeyguardManager) context.getSystemService(Contex t.KEYGUARD_SERVICE); 812 mKeyguardManager = (KeyguardManager) context.getSystemService(Contex t.KEYGUARD_SERVICE);
769 } 813 }
770 if (!ApiCompatibilityUtils.isInteractive(context)) return false; 814 if (!ApiCompatibilityUtils.isInteractive(context)) return false;
771 return !ApiCompatibilityUtils.isDeviceProvisioned(context) 815 return !ApiCompatibilityUtils.isDeviceProvisioned(context)
772 || !mKeyguardManager.inKeyguardRestrictedInputMode(); 816 || !mKeyguardManager.inKeyguardRestrictedInputMode();
773 } 817 }
774 818
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 if (transitionType == PageTransition.TYPED) { 1022 if (transitionType == PageTransition.TYPED) {
979 return transitionType; 1023 return transitionType;
980 } else if (transitionType != PageTransition.LINK 1024 } else if (transitionType != PageTransition.LINK
981 && isIntentChromeOrFirstParty(intent, context)) { 1025 && isIntentChromeOrFirstParty(intent, context)) {
982 // 1st party applications may specify any transition type. 1026 // 1st party applications may specify any transition type.
983 return transitionType; 1027 return transitionType;
984 } 1028 }
985 return defaultTransition; 1029 return defaultTransition;
986 } 1030 }
987 } 1031 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698