OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.externalnav; |
| 6 |
| 7 import android.content.Intent; |
| 8 |
| 9 import org.chromium.chrome.browser.IntentHandler; |
| 10 import org.chromium.chrome.browser.util.IntentUtils; |
| 11 |
| 12 import java.security.SecureRandom; |
| 13 import java.util.Arrays; |
| 14 |
| 15 /** |
| 16 * This class hold a token for the most recent launched external intent that has |
| 17 * user gesture. If the external intent resolves to chrome itself, the user |
| 18 * gesture will be applied to the new url request. Since there could be at most |
| 19 * one intent chooser at a time, this class only stores the most recent intent |
| 20 * that has user gesture. A previously launched intent with user gesture will |
| 21 * have its token invalidated if a new one comes. |
| 22 */ |
| 23 public class IntentWithGesturesHandler { |
| 24 /** |
| 25 * Extra to record whether the intent is launched by user gesture. |
| 26 */ |
| 27 public static final String EXTRA_USER_GESTURE_TOKEN = |
| 28 "org.chromium.chrome.browser.user_gesture_token"; |
| 29 |
| 30 private static final Object INSTANCE_LOCK = new Object(); |
| 31 private static IntentWithGesturesHandler sIntentWithGesturesHandler; |
| 32 private SecureRandom mSecureRandom; |
| 33 private byte[] mIntentToken; |
| 34 private String mUri; |
| 35 |
| 36 /** |
| 37 * Get the singleton instance of this object. |
| 38 */ |
| 39 public static IntentWithGesturesHandler getInstance() { |
| 40 synchronized (INSTANCE_LOCK) { |
| 41 if (sIntentWithGesturesHandler == null) { |
| 42 sIntentWithGesturesHandler = new IntentWithGesturesHandler(); |
| 43 } |
| 44 } |
| 45 return sIntentWithGesturesHandler; |
| 46 } |
| 47 |
| 48 private IntentWithGesturesHandler() { |
| 49 mSecureRandom = new SecureRandom(); |
| 50 } |
| 51 |
| 52 /** |
| 53 * Generate a new token for the intent that has user gesture. This will |
| 54 * invalidate the token on the previously launched intent with user gesture. |
| 55 * |
| 56 * @param intent Intent with user gesture. |
| 57 */ |
| 58 public void onNewIntentWithGesture(Intent intent) { |
| 59 mIntentToken = new byte[32]; |
| 60 mSecureRandom.nextBytes(mIntentToken); |
| 61 intent.putExtra(EXTRA_USER_GESTURE_TOKEN, mIntentToken); |
| 62 mUri = IntentHandler.getUrlFromIntent(intent); |
| 63 } |
| 64 |
| 65 /** |
| 66 * Get the user gesture from the intent and clear the stored token. |
| 67 * |
| 68 * @param intent Intent that is used to launch chrome. |
| 69 * @return true if the intent has user gesture, or false otherwise. |
| 70 */ |
| 71 public boolean getUserGestureAndClear(Intent intent) { |
| 72 if (mIntentToken == null || mUri == null) return false; |
| 73 byte[] bytes = IntentUtils.safeGetByteArrayExtra(intent, EXTRA_USER_GEST
URE_TOKEN); |
| 74 boolean ret = (bytes != null) && Arrays.equals(bytes, mIntentToken) |
| 75 && mUri.equals(IntentHandler.getUrlFromIntent(intent)); |
| 76 clear(); |
| 77 return ret; |
| 78 } |
| 79 |
| 80 /** |
| 81 * Clear the gesture token. |
| 82 */ |
| 83 public void clear() { |
| 84 mIntentToken = null; |
| 85 mUri = null; |
| 86 } |
| 87 } |
OLD | NEW |