Index: chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java |
index e0e242be504ec625522842e3e5b488246395c6e3..b3f47b054cf2d065728c874337159ae30a8ee555 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java |
@@ -10,6 +10,7 @@ import android.app.SearchManager; |
import android.content.ComponentName; |
import android.content.Context; |
import android.content.Intent; |
+import android.content.IntentFilter; |
import android.net.Uri; |
import android.os.Bundle; |
import android.os.SystemClock; |
@@ -226,6 +227,11 @@ public class IntentHandler { |
private final String mPackageName; |
private KeyguardManager mKeyguardManager; |
+ /** |
+ * Receiver for screen unlock broadcast. |
+ */ |
+ private KeyguardBroadcastReceiver mKeyguardBroadcastReceiver; |
+ |
public static enum TabOpenType { |
OPEN_NEW_TAB, |
// Tab is reused only if the URLs perfectly match. |
@@ -331,13 +337,30 @@ public class IntentHandler { |
} |
} |
+ @VisibleForTesting |
+ void tryUnregisterLockscreenIntentReceiver(Context context, Intent intent) { |
+ // Only unregister receiver when the intent was specially marked or the receiver no longer |
+ // contain any valid deferred intent. |
+ // If the intent does not contain the special mark, it should be treated as normal intent |
+ // instead. This is helping the scenario when the screen is unlocked, another intent is |
+ // 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
|
+ if (mKeyguardBroadcastReceiver != null |
+ && !mKeyguardBroadcastReceiver.hasValidDeferredIntent(intent)) { |
+ context.unregisterReceiver(mKeyguardBroadcastReceiver); |
+ mKeyguardBroadcastReceiver = null; |
+ } |
+ } |
+ |
/** |
* Handles an Intent after the ChromeTabbedActivity decides that it shouldn't ignore the |
* Intent. |
- * |
+ * @param context Android Context. |
+ * @param intent Target intent. |
* @return Whether the Intent was successfully handled. |
*/ |
boolean onNewIntent(Context context, Intent intent) { |
+ tryUnregisterLockscreenIntentReceiver(context, intent); |
+ |
assert intentHasValidUrl(intent); |
String url = getUrlFromIntent(intent); |
boolean hasUserGesture = |
@@ -688,13 +711,33 @@ public class IntentHandler { |
// We must check for screen state at this point. |
// These might be slow. |
boolean internalOrVisible = isInternal || isIntentUserVisible(context); |
- return !internalOrVisible; |
+ if (!internalOrVisible) { |
+ // Register keyguard broadcast receiver to receive ACTION_USER_PRESENT when the |
+ // screen is unlocked. |
+ // Avoid register KeyguardBroadcastReceiver if there is already one cached to allow |
+ // unregister on the same instance. |
+ // The ACTION_USER_PRESENT is sent by platform to indicates when user is present. |
+ if (mKeyguardBroadcastReceiver == null) { |
+ mKeyguardBroadcastReceiver = new KeyguardBroadcastReceiver(intent); |
+ context.registerReceiver(mKeyguardBroadcastReceiver, |
+ new IntentFilter(Intent.ACTION_USER_PRESENT)); |
+ } else { |
+ mKeyguardBroadcastReceiver.updateDeferredIntent(intent); |
+ } |
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
|
+ return true; |
+ } |
+ return false; |
} catch (Throwable t) { |
return true; |
} |
} |
@VisibleForTesting |
+ void setKeyguardBroadcastReceiverForTesting(KeyguardBroadcastReceiver receiver) { |
+ mKeyguardBroadcastReceiver = receiver; |
+ } |
+ |
+ @VisibleForTesting |
boolean intentHasValidUrl(Intent intent) { |
String url = getUrlFromIntent(intent); |
@@ -761,7 +804,8 @@ public class IntentHandler { |
return false; |
} |
- private boolean isIntentUserVisible(Context context) { |
+ @VisibleForTesting |
+ boolean isIntentUserVisible(Context context) { |
// Only process Intents if the screen is on and the device is unlocked; |
// i.e. the user will see what is going on. |
if (mKeyguardManager == null) { |