| Index: chrome/android/java/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandler.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandler.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1fd2e78303a83f81179d38b60d2d3c0b18a7ff8c
|
| --- /dev/null
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandler.java
|
| @@ -0,0 +1,87 @@
|
| +// Copyright 2015 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.externalnav;
|
| +
|
| +import android.content.Intent;
|
| +
|
| +import org.chromium.chrome.browser.IntentHandler;
|
| +import org.chromium.chrome.browser.util.IntentUtils;
|
| +
|
| +import java.security.SecureRandom;
|
| +import java.util.Arrays;
|
| +
|
| +/**
|
| + * This class hold a token for the most recent launched external intent that has
|
| + * user gesture. If the external intent resolves to chrome itself, the user
|
| + * gesture will be applied to the new url request. Since there could be at most
|
| + * one intent chooser at a time, this class only stores the most recent intent
|
| + * that has user gesture. A previously launched intent with user gesture will
|
| + * have its token invalidated if a new one comes.
|
| + */
|
| +public class IntentWithGesturesHandler {
|
| + /**
|
| + * Extra to record whether the intent is launched by user gesture.
|
| + */
|
| + public static final String EXTRA_USER_GESTURE_TOKEN =
|
| + "org.chromium.chrome.browser.user_gesture_token";
|
| +
|
| + private static final Object INSTANCE_LOCK = new Object();
|
| + private static IntentWithGesturesHandler sIntentWithGesturesHandler;
|
| + private SecureRandom mSecureRandom;
|
| + private byte[] mIntentToken;
|
| + private String mUri;
|
| +
|
| + /**
|
| + * Get the singleton instance of this object.
|
| + */
|
| + public static IntentWithGesturesHandler getInstance() {
|
| + synchronized (INSTANCE_LOCK) {
|
| + if (sIntentWithGesturesHandler == null) {
|
| + sIntentWithGesturesHandler = new IntentWithGesturesHandler();
|
| + }
|
| + }
|
| + return sIntentWithGesturesHandler;
|
| + }
|
| +
|
| + private IntentWithGesturesHandler() {
|
| + mSecureRandom = new SecureRandom();
|
| + }
|
| +
|
| + /**
|
| + * Generate a new token for the intent that has user gesture. This will
|
| + * invalidate the token on the previously launched intent with user gesture.
|
| + *
|
| + * @param intent Intent with user gesture.
|
| + */
|
| + public void onNewIntentWithGesture(Intent intent) {
|
| + mIntentToken = new byte[32];
|
| + mSecureRandom.nextBytes(mIntentToken);
|
| + intent.putExtra(EXTRA_USER_GESTURE_TOKEN, mIntentToken);
|
| + mUri = IntentHandler.getUrlFromIntent(intent);
|
| + }
|
| +
|
| + /**
|
| + * Get the user gesture from the intent and clear the stored token.
|
| + *
|
| + * @param intent Intent that is used to launch chrome.
|
| + * @return true if the intent has user gesture, or false otherwise.
|
| + */
|
| + public boolean getUserGestureAndClear(Intent intent) {
|
| + if (mIntentToken == null || mUri == null) return false;
|
| + byte[] bytes = IntentUtils.safeGetByteArrayExtra(intent, EXTRA_USER_GESTURE_TOKEN);
|
| + boolean ret = (bytes != null) && Arrays.equals(bytes, mIntentToken)
|
| + && mUri.equals(IntentHandler.getUrlFromIntent(intent));
|
| + clear();
|
| + return ret;
|
| + }
|
| +
|
| + /**
|
| + * Clear the gesture token.
|
| + */
|
| + public void clear() {
|
| + mIntentToken = null;
|
| + mUri = null;
|
| + }
|
| +}
|
|
|