Index: chrome/android/java/src/org/chromium/chrome/browser/DelayedScreenLockIntentHandler.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DelayedScreenLockIntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/DelayedScreenLockIntentHandler.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..374676648702659956b606ffe1d4add197350293 |
--- /dev/null |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/DelayedScreenLockIntentHandler.java |
@@ -0,0 +1,96 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.browser; |
+ |
+import android.content.BroadcastReceiver; |
+import android.content.Context; |
+import android.content.Intent; |
+import android.content.IntentFilter; |
+import android.os.Handler; |
+import android.os.SystemClock; |
+ |
+import org.chromium.base.ContextUtils; |
+ |
+/** |
+ * Intent handler that is specific for the situation when the screen is unlocked from pin, pattern, |
+ * or password. |
+ * This class handles exactly one intent unlock + dispatch at a time. It could be reused by calling |
+ * updateDeferredIntent with a new intent. |
+ */ |
+public class DelayedScreenLockIntentHandler extends BroadcastReceiver { |
+ private static final int VALID_DEFERRED_PERIOD_MS = 10000; |
+ |
+ private final Handler mTaskHandler; |
+ private final Runnable mUnregisterTask; |
+ |
+ private Intent mDeferredIntent; |
+ private long mDeferredIntentCreatedTime; |
+ private boolean mReceiverRegistered; |
+ |
+ public DelayedScreenLockIntentHandler() { |
+ mTaskHandler = new Handler(); |
+ mUnregisterTask = new Runnable() { |
+ @Override |
+ public void run() { |
+ updateDeferredIntent(null); |
+ } |
+ }; |
+ } |
+ |
+ @Override |
+ public void onReceive(Context context, Intent intent) { |
+ assert Intent.ACTION_USER_PRESENT.equals(intent.getAction()); |
+ |
+ if (Intent.ACTION_USER_PRESENT.equals(intent.getAction()) && mDeferredIntent != null) { |
+ context.startActivity(mDeferredIntent); |
+ // Prevent the broadcast receiver from firing intent unexpectedly. |
+ updateDeferredIntent(null); |
+ } |
+ } |
+ |
+ /** |
+ * Update the deferred intent with the target intent, also reset the deferred intent's lifecycle |
+ * @param intent Target intent |
+ */ |
+ public void updateDeferredIntent(final Intent intent) { |
+ mTaskHandler.removeCallbacks(mUnregisterTask); |
+ |
+ if (intent == null) { |
+ unregisterReceiver(); |
+ mDeferredIntent = null; |
+ return; |
+ } |
+ |
+ mDeferredIntent = intent; |
+ mDeferredIntentCreatedTime = SystemClock.elapsedRealtime(); |
+ registerReceiver(); |
+ mTaskHandler.postDelayed(mUnregisterTask, VALID_DEFERRED_PERIOD_MS); |
+ } |
+ |
+ /** |
+ * Register to receive ACTION_USER_PRESENT when the screen is unlocked. |
+ * The ACTION_USER_PRESENT is sent by platform to indicates when user is present. |
+ */ |
+ private void registerReceiver() { |
+ if (mReceiverRegistered) return; |
+ |
+ ContextUtils.getApplicationContext() |
+ .registerReceiver(this, new IntentFilter(Intent.ACTION_USER_PRESENT)); |
+ mReceiverRegistered = true; |
+ } |
+ |
+ /** |
+ * Unregister the receiver in one of the following situations |
+ * - When the deferred intent expires |
+ * - When updateDeferredIntent(null) called |
+ * - When the deferred intent has been fired |
+ */ |
+ private void unregisterReceiver() { |
+ if (!mReceiverRegistered) return; |
+ |
+ ContextUtils.getApplicationContext().unregisterReceiver(this); |
+ mReceiverRegistered = false; |
+ } |
+} |