| OLD | NEW |
| 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.customtabs; | 5 package org.chromium.chrome.browser.customtabs; |
| 6 | 6 |
| 7 import android.content.ComponentName; | 7 import android.content.ComponentName; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.content.Intent; | 9 import android.content.Intent; |
| 10 import android.content.ServiceConnection; | 10 import android.content.ServiceConnection; |
| 11 import android.content.pm.PackageManager; | 11 import android.content.pm.PackageManager; |
| 12 import android.os.IBinder; | 12 import android.os.IBinder; |
| 13 import android.os.RemoteException; | |
| 14 import android.os.SystemClock; | 13 import android.os.SystemClock; |
| 15 import android.support.customtabs.ICustomTabsCallback; | 14 import android.support.customtabs.CustomTabsCallback; |
| 15 import android.support.customtabs.CustomTabsSessionToken; |
| 16 import android.text.TextUtils; | 16 import android.text.TextUtils; |
| 17 import android.util.SparseBooleanArray; | 17 import android.util.SparseBooleanArray; |
| 18 | 18 |
| 19 import org.chromium.base.ThreadUtils; | |
| 20 import org.chromium.base.VisibleForTesting; | 19 import org.chromium.base.VisibleForTesting; |
| 21 import org.chromium.base.annotations.SuppressFBWarnings; | 20 import org.chromium.base.annotations.SuppressFBWarnings; |
| 22 import org.chromium.base.metrics.RecordHistogram; | 21 import org.chromium.base.metrics.RecordHistogram; |
| 23 import org.chromium.chrome.browser.IntentHandler; | 22 import org.chromium.chrome.browser.IntentHandler; |
| 24 import org.chromium.chrome.browser.util.UrlUtilities; | 23 import org.chromium.chrome.browser.util.UrlUtilities; |
| 25 import org.chromium.content_public.common.Referrer; | 24 import org.chromium.content_public.common.Referrer; |
| 26 | 25 |
| 27 import java.util.ArrayList; | 26 import java.util.ArrayList; |
| 28 import java.util.Arrays; | 27 import java.util.Arrays; |
| 29 import java.util.HashMap; | 28 import java.util.HashMap; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 40 @VisibleForTesting static final int BAD_PREDICTION = 2; | 39 @VisibleForTesting static final int BAD_PREDICTION = 2; |
| 41 private static final int PREDICTION_STATUS_COUNT = 3; | 40 private static final int PREDICTION_STATUS_COUNT = 3; |
| 42 // Values for the "CustomTabs.CalledWarmup" UMA histogram. Append-only. | 41 // Values for the "CustomTabs.CalledWarmup" UMA histogram. Append-only. |
| 43 @VisibleForTesting static final int NO_SESSION_NO_WARMUP = 0; | 42 @VisibleForTesting static final int NO_SESSION_NO_WARMUP = 0; |
| 44 @VisibleForTesting static final int NO_SESSION_WARMUP = 1; | 43 @VisibleForTesting static final int NO_SESSION_WARMUP = 1; |
| 45 @VisibleForTesting static final int SESSION_NO_WARMUP_ALREADY_CALLED = 2; | 44 @VisibleForTesting static final int SESSION_NO_WARMUP_ALREADY_CALLED = 2; |
| 46 @VisibleForTesting static final int SESSION_NO_WARMUP_NOT_CALLED = 3; | 45 @VisibleForTesting static final int SESSION_NO_WARMUP_NOT_CALLED = 3; |
| 47 @VisibleForTesting static final int SESSION_WARMUP = 4; | 46 @VisibleForTesting static final int SESSION_WARMUP = 4; |
| 48 @VisibleForTesting static final int SESSION_WARMUP_COUNT = 5; | 47 @VisibleForTesting static final int SESSION_WARMUP_COUNT = 5; |
| 49 | 48 |
| 49 /** To be called when a client gets disconnected. */ |
| 50 public interface DisconnectCallback { public void run(CustomTabsSessionToken
session); } |
| 51 |
| 50 /** Per-session values. */ | 52 /** Per-session values. */ |
| 51 private static class SessionParams { | 53 private static class SessionParams { |
| 52 public final int uid; | 54 public final int uid; |
| 55 public final DisconnectCallback disconnectCallback; |
| 53 public final String packageName; | 56 public final String packageName; |
| 54 public final ICustomTabsCallback callback; | |
| 55 public final IBinder.DeathRecipient deathRecipient; | |
| 56 public boolean mIgnoreFragments; | 57 public boolean mIgnoreFragments; |
| 57 private boolean mShouldHideDomain; | 58 private boolean mShouldHideDomain; |
| 58 private boolean mShouldPrerenderOnCellular; | 59 private boolean mShouldPrerenderOnCellular; |
| 59 private ServiceConnection mKeepAliveConnection; | 60 private ServiceConnection mKeepAliveConnection; |
| 60 private String mPredictedUrl; | 61 private String mPredictedUrl; |
| 61 private long mLastMayLaunchUrlTimestamp; | 62 private long mLastMayLaunchUrlTimestamp; |
| 62 | 63 |
| 63 public SessionParams(Context context, int uid, ICustomTabsCallback callb
ack, | 64 public SessionParams(Context context, int uid, DisconnectCallback callba
ck) { |
| 64 IBinder.DeathRecipient deathRecipient) { | |
| 65 this.uid = uid; | 65 this.uid = uid; |
| 66 packageName = getPackageName(context, uid); | 66 packageName = getPackageName(context, uid); |
| 67 this.callback = callback; | 67 disconnectCallback = callback; |
| 68 this.deathRecipient = deathRecipient; | |
| 69 } | 68 } |
| 70 | 69 |
| 71 private static String getPackageName(Context context, int uid) { | 70 private static String getPackageName(Context context, int uid) { |
| 72 PackageManager packageManager = context.getPackageManager(); | 71 PackageManager packageManager = context.getPackageManager(); |
| 73 String[] packageList = packageManager.getPackagesForUid(uid); | 72 String[] packageList = packageManager.getPackagesForUid(uid); |
| 74 if (packageList.length != 1 || TextUtils.isEmpty(packageList[0])) re
turn null; | 73 if (packageList.length != 1 || TextUtils.isEmpty(packageList[0])) re
turn null; |
| 75 return packageList[0]; | 74 return packageList[0]; |
| 76 } | 75 } |
| 77 | 76 |
| 78 public ServiceConnection getKeepAliveConnection() { | 77 public ServiceConnection getKeepAliveConnection() { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 90 | 89 |
| 91 public String getPredictedUrl() { | 90 public String getPredictedUrl() { |
| 92 return mPredictedUrl; | 91 return mPredictedUrl; |
| 93 } | 92 } |
| 94 | 93 |
| 95 public long getLastMayLaunchUrlTimestamp() { | 94 public long getLastMayLaunchUrlTimestamp() { |
| 96 return mLastMayLaunchUrlTimestamp; | 95 return mLastMayLaunchUrlTimestamp; |
| 97 } | 96 } |
| 98 } | 97 } |
| 99 | 98 |
| 100 /** To be called when a client gets disconnected. */ | |
| 101 public interface DisconnectCallback { public void run(IBinder session); } | |
| 102 | |
| 103 private final Context mContext; | 99 private final Context mContext; |
| 104 private final Map<IBinder, SessionParams> mSessionParams = new HashMap<>(); | 100 private final Map<CustomTabsSessionToken, SessionParams> mSessionParams = ne
w HashMap<>(); |
| 105 private final SparseBooleanArray mUidHasCalledWarmup = new SparseBooleanArra
y(); | 101 private final SparseBooleanArray mUidHasCalledWarmup = new SparseBooleanArra
y(); |
| 106 private boolean mWarmupHasBeenCalled = false; | 102 private boolean mWarmupHasBeenCalled = false; |
| 107 | 103 |
| 108 public ClientManager(Context context) { | 104 public ClientManager(Context context) { |
| 109 mContext = context.getApplicationContext(); | 105 mContext = context.getApplicationContext(); |
| 110 RequestThrottler.loadInBackground(mContext); | 106 RequestThrottler.loadInBackground(mContext); |
| 111 } | 107 } |
| 112 | 108 |
| 113 /** Creates a new session. | 109 /** Creates a new session. |
| 114 * | 110 * |
| 115 * @param cb Callback provided by the client. | 111 * @param session Session provided by the client. |
| 116 * @param uid Client UID, as returned by Binder.getCallingUid(), | 112 * @param uid Client UID, as returned by Binder.getCallingUid(), |
| 117 * @param onDisconnect To be called on the UI thread when a client gets disc
onnected. | 113 * @param onDisconnect To be called on the UI thread when a client gets disc
onnected. |
| 118 * @return true for success. | 114 * @return true for success. |
| 119 */ | 115 */ |
| 120 public boolean newSession( | 116 public boolean newSession( |
| 121 ICustomTabsCallback cb, int uid, final DisconnectCallback onDisconne
ct) { | 117 CustomTabsSessionToken session, int uid, DisconnectCallback onDiscon
nect) { |
| 122 if (cb == null) return false; | 118 if (session == null) return false; |
| 123 final IBinder session = cb.asBinder(); | 119 SessionParams params = new SessionParams(mContext, uid, onDisconnect); |
| 124 IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() { | |
| 125 @Override | |
| 126 public void binderDied() { | |
| 127 ThreadUtils.postOnUiThread(new Runnable() { | |
| 128 @Override | |
| 129 public void run() { | |
| 130 cleanupSession(session); | |
| 131 onDisconnect.run(session); | |
| 132 } | |
| 133 }); | |
| 134 } | |
| 135 }; | |
| 136 SessionParams params = new SessionParams(mContext, uid, cb, deathRecipie
nt); | |
| 137 synchronized (this) { | 120 synchronized (this) { |
| 138 if (mSessionParams.containsKey(session)) return false; | 121 if (mSessionParams.containsKey(session)) return false; |
| 139 try { | |
| 140 session.linkToDeath(deathRecipient, 0); | |
| 141 } catch (RemoteException e) { | |
| 142 // The return code doesn't matter, because this executes when | |
| 143 // the caller has died. | |
| 144 return false; | |
| 145 } | |
| 146 mSessionParams.put(session, params); | 122 mSessionParams.put(session, params); |
| 147 } | 123 } |
| 148 return true; | 124 return true; |
| 149 } | 125 } |
| 150 | 126 |
| 151 /** | 127 /** |
| 152 * Records that {@link CustomTabsConnection#warmup(long)} has been called fr
om the given uid. | 128 * Records that {@link CustomTabsConnection#warmup(long)} has been called fr
om the given uid. |
| 153 */ | 129 */ |
| 154 public synchronized void recordUidHasCalledWarmup(int uid) { | 130 public synchronized void recordUidHasCalledWarmup(int uid) { |
| 155 mWarmupHasBeenCalled = true; | 131 mWarmupHasBeenCalled = true; |
| 156 mUidHasCalledWarmup.put(uid, true); | 132 mUidHasCalledWarmup.put(uid, true); |
| 157 } | 133 } |
| 158 | 134 |
| 159 /** Updates the client behavior stats and returns whether speculation is all
owed. | 135 /** Updates the client behavior stats and returns whether speculation is all
owed. |
| 160 * | 136 * |
| 161 * @param session Client session. | 137 * @param session Client session. |
| 162 * @param uid As returned by Binder.getCallingUid(). | 138 * @param uid As returned by Binder.getCallingUid(). |
| 163 * @param url Predicted URL. | 139 * @param url Predicted URL. |
| 164 * @return true if speculation is allowed. | 140 * @return true if speculation is allowed. |
| 165 */ | 141 */ |
| 166 public synchronized boolean updateStatsAndReturnWhetherAllowed( | 142 public synchronized boolean updateStatsAndReturnWhetherAllowed( |
| 167 IBinder session, int uid, String url) { | 143 CustomTabsSessionToken session, int uid, String url) { |
| 168 SessionParams params = mSessionParams.get(session); | 144 SessionParams params = mSessionParams.get(session); |
| 169 if (params == null || params.uid != uid) return false; | 145 if (params == null || params.uid != uid) return false; |
| 170 params.setPredictionMetrics(url, SystemClock.elapsedRealtime()); | 146 params.setPredictionMetrics(url, SystemClock.elapsedRealtime()); |
| 171 RequestThrottler throttler = RequestThrottler.getForUid(mContext, uid); | 147 RequestThrottler throttler = RequestThrottler.getForUid(mContext, uid); |
| 172 return throttler.updateStatsAndReturnWhetherAllowed(); | 148 return throttler.updateStatsAndReturnWhetherAllowed(); |
| 173 } | 149 } |
| 174 | 150 |
| 175 @VisibleForTesting | 151 @VisibleForTesting |
| 176 synchronized int getWarmupState(IBinder session) { | 152 synchronized int getWarmupState(CustomTabsSessionToken session) { |
| 177 SessionParams params = mSessionParams.get(session); | 153 SessionParams params = mSessionParams.get(session); |
| 178 boolean hasValidSession = params != null; | 154 boolean hasValidSession = params != null; |
| 179 boolean hasUidCalledWarmup = hasValidSession && mUidHasCalledWarmup.get(
params.uid); | 155 boolean hasUidCalledWarmup = hasValidSession && mUidHasCalledWarmup.get(
params.uid); |
| 180 int result = mWarmupHasBeenCalled ? NO_SESSION_WARMUP : NO_SESSION_NO_WA
RMUP; | 156 int result = mWarmupHasBeenCalled ? NO_SESSION_WARMUP : NO_SESSION_NO_WA
RMUP; |
| 181 if (hasValidSession) { | 157 if (hasValidSession) { |
| 182 if (hasUidCalledWarmup) { | 158 if (hasUidCalledWarmup) { |
| 183 result = SESSION_WARMUP; | 159 result = SESSION_WARMUP; |
| 184 } else { | 160 } else { |
| 185 result = mWarmupHasBeenCalled ? SESSION_NO_WARMUP_ALREADY_CALLED | 161 result = mWarmupHasBeenCalled ? SESSION_NO_WARMUP_ALREADY_CALLED |
| 186 : SESSION_NO_WARMUP_NOT_CALLED; | 162 : SESSION_NO_WARMUP_NOT_CALLED; |
| 187 } | 163 } |
| 188 } | 164 } |
| 189 return result; | 165 return result; |
| 190 } | 166 } |
| 191 | 167 |
| 192 @VisibleForTesting | 168 @VisibleForTesting |
| 193 synchronized int getPredictionOutcome(IBinder session, String url) { | 169 synchronized int getPredictionOutcome(CustomTabsSessionToken session, String
url) { |
| 194 SessionParams params = mSessionParams.get(session); | 170 SessionParams params = mSessionParams.get(session); |
| 195 if (params == null) return NO_PREDICTION; | 171 if (params == null) return NO_PREDICTION; |
| 196 | 172 |
| 197 String predictedUrl = params.getPredictedUrl(); | 173 String predictedUrl = params.getPredictedUrl(); |
| 198 if (predictedUrl == null) return NO_PREDICTION; | 174 if (predictedUrl == null) return NO_PREDICTION; |
| 199 | 175 |
| 200 boolean urlsMatch = TextUtils.equals(predictedUrl, url) | 176 boolean urlsMatch = TextUtils.equals(predictedUrl, url) |
| 201 || (params.mIgnoreFragments | 177 || (params.mIgnoreFragments |
| 202 && UrlUtilities.urlsMatchIgnoringFragments(predictedUrl,
url)); | 178 && UrlUtilities.urlsMatchIgnoringFragments(predictedUrl,
url)); |
| 203 return urlsMatch ? GOOD_PREDICTION : BAD_PREDICTION; | 179 return urlsMatch ? GOOD_PREDICTION : BAD_PREDICTION; |
| 204 } | 180 } |
| 205 | 181 |
| 206 /** | 182 /** |
| 207 * Registers that a client has launched a URL inside a Custom Tab. | 183 * Registers that a client has launched a URL inside a Custom Tab. |
| 208 */ | 184 */ |
| 209 public synchronized void registerLaunch(IBinder session, String url) { | 185 public synchronized void registerLaunch(CustomTabsSessionToken session, Stri
ng url) { |
| 210 int outcome = getPredictionOutcome(session, url); | 186 int outcome = getPredictionOutcome(session, url); |
| 211 RecordHistogram.recordEnumeratedHistogram( | 187 RecordHistogram.recordEnumeratedHistogram( |
| 212 "CustomTabs.PredictionStatus", outcome, PREDICTION_STATUS_COUNT)
; | 188 "CustomTabs.PredictionStatus", outcome, PREDICTION_STATUS_COUNT)
; |
| 213 | 189 |
| 214 SessionParams params = mSessionParams.get(session); | 190 SessionParams params = mSessionParams.get(session); |
| 215 if (outcome == GOOD_PREDICTION) { | 191 if (outcome == GOOD_PREDICTION) { |
| 216 long elapsedTimeMs = SystemClock.elapsedRealtime() | 192 long elapsedTimeMs = SystemClock.elapsedRealtime() |
| 217 - params.getLastMayLaunchUrlTimestamp(); | 193 - params.getLastMayLaunchUrlTimestamp(); |
| 218 RequestThrottler.getForUid(mContext, params.uid).registerSuccess( | 194 RequestThrottler.getForUid(mContext, params.uid).registerSuccess( |
| 219 params.mPredictedUrl); | 195 params.mPredictedUrl); |
| 220 RecordHistogram.recordCustomTimesHistogram("CustomTabs.PredictionToL
aunch", | 196 RecordHistogram.recordCustomTimesHistogram("CustomTabs.PredictionToL
aunch", |
| 221 elapsedTimeMs, 1, TimeUnit.MINUTES.toMillis(3), TimeUnit.MIL
LISECONDS, 100); | 197 elapsedTimeMs, 1, TimeUnit.MINUTES.toMillis(3), TimeUnit.MIL
LISECONDS, 100); |
| 222 } | 198 } |
| 223 RecordHistogram.recordEnumeratedHistogram( | 199 RecordHistogram.recordEnumeratedHistogram( |
| 224 "CustomTabs.WarmupStateOnLaunch", getWarmupState(session), SESSI
ON_WARMUP_COUNT); | 200 "CustomTabs.WarmupStateOnLaunch", getWarmupState(session), SESSI
ON_WARMUP_COUNT); |
| 225 if (params != null) params.setPredictionMetrics(null, 0); | 201 if (params != null) params.setPredictionMetrics(null, 0); |
| 226 } | 202 } |
| 227 | 203 |
| 228 /** | 204 /** |
| 229 * @return The referrer that is associated with the client owning given sess
ion. | 205 * @return The referrer that is associated with the client owning given sess
ion. |
| 230 */ | 206 */ |
| 231 public synchronized Referrer getReferrerForSession(IBinder session) { | 207 public synchronized Referrer getReferrerForSession(CustomTabsSessionToken se
ssion) { |
| 232 SessionParams params = mSessionParams.get(session); | 208 SessionParams params = mSessionParams.get(session); |
| 233 if (params == null) return null; | 209 if (params == null) return null; |
| 234 final String packageName = params.packageName; | 210 final String packageName = params.packageName; |
| 235 return IntentHandler.constructValidReferrerForAuthority(packageName); | 211 return IntentHandler.constructValidReferrerForAuthority(packageName); |
| 236 } | 212 } |
| 237 | 213 |
| 238 /** | 214 /** |
| 239 * @return The package name associated with the client owning the given sess
ion. | 215 * @return The package name associated with the client owning the given sess
ion. |
| 240 */ | 216 */ |
| 241 public synchronized String getClientPackageNameForSession(IBinder session) { | 217 public synchronized String getClientPackageNameForSession(CustomTabsSessionT
oken session) { |
| 242 SessionParams params = mSessionParams.get(session); | 218 SessionParams params = mSessionParams.get(session); |
| 243 return params == null ? null : params.packageName; | 219 return params == null ? null : params.packageName; |
| 244 } | 220 } |
| 245 | 221 |
| 246 /** | 222 /** |
| 247 * @return The callback {@link IBinder} for the given session. | 223 * @return The callback {@link CustomTabsSessionToken} for the given session
. |
| 248 */ | 224 */ |
| 249 public synchronized ICustomTabsCallback getCallbackForSession(IBinder sessio
n) { | 225 public synchronized CustomTabsCallback getCallbackForSession(CustomTabsSessi
onToken session) { |
| 250 SessionParams params = mSessionParams.get(session); | 226 return session != null ? session.getCallback() : null; |
| 251 return params != null ? params.callback : null; | |
| 252 } | 227 } |
| 253 | 228 |
| 254 /** | 229 /** |
| 255 * @return Whether the urlbar should be hidden for the session on first page
load. Urls are | 230 * @return Whether the urlbar should be hidden for the session on first page
load. Urls are |
| 256 * foced to show up after the user navigates away. | 231 * foced to show up after the user navigates away. |
| 257 */ | 232 */ |
| 258 public synchronized boolean shouldHideDomainForSession(IBinder session) { | 233 public synchronized boolean shouldHideDomainForSession(CustomTabsSessionToke
n session) { |
| 259 SessionParams params = mSessionParams.get(session); | 234 SessionParams params = mSessionParams.get(session); |
| 260 return params != null ? params.mShouldHideDomain : false; | 235 return params != null ? params.mShouldHideDomain : false; |
| 261 } | 236 } |
| 262 | 237 |
| 263 /** | 238 /** |
| 264 * Sets whether the urlbar should be hidden for a given session. | 239 * Sets whether the urlbar should be hidden for a given session. |
| 265 */ | 240 */ |
| 266 public synchronized void setHideDomainForSession(IBinder session, boolean hi
de) { | 241 public synchronized void setHideDomainForSession(CustomTabsSessionToken sess
ion, boolean hide) { |
| 267 SessionParams params = mSessionParams.get(session); | 242 SessionParams params = mSessionParams.get(session); |
| 268 if (params != null) params.mShouldHideDomain = hide; | 243 if (params != null) params.mShouldHideDomain = hide; |
| 269 } | 244 } |
| 270 | 245 |
| 271 /** | 246 /** |
| 272 * @return Whether the fragment should be ignored for prerender matching. | 247 * @return Whether the fragment should be ignored for prerender matching. |
| 273 */ | 248 */ |
| 274 public synchronized boolean getIgnoreFragmentsForSession(IBinder session) { | 249 public synchronized boolean getIgnoreFragmentsForSession(CustomTabsSessionTo
ken session) { |
| 275 SessionParams params = mSessionParams.get(session); | 250 SessionParams params = mSessionParams.get(session); |
| 276 return params == null ? false : params.mIgnoreFragments; | 251 return params == null ? false : params.mIgnoreFragments; |
| 277 } | 252 } |
| 278 | 253 |
| 279 /** Sets whether the fragment should be ignored for prerender matching. */ | 254 /** Sets whether the fragment should be ignored for prerender matching. */ |
| 280 public synchronized void setIgnoreFragmentsForSession(IBinder session, boole
an value) { | 255 public synchronized void setIgnoreFragmentsForSession( |
| 256 CustomTabsSessionToken session, boolean value) { |
| 281 SessionParams params = mSessionParams.get(session); | 257 SessionParams params = mSessionParams.get(session); |
| 282 if (params != null) params.mIgnoreFragments = value; | 258 if (params != null) params.mIgnoreFragments = value; |
| 283 } | 259 } |
| 284 | 260 |
| 285 /** | 261 /** |
| 286 * @return Whether prerender should be turned on for cellular networks for g
iven session. | 262 * @return Whether prerender should be turned on for cellular networks for g
iven session. |
| 287 */ | 263 */ |
| 288 public synchronized boolean shouldPrerenderOnCellularForSession(IBinder sess
ion) { | 264 public synchronized boolean shouldPrerenderOnCellularForSession( |
| 265 CustomTabsSessionToken session) { |
| 289 SessionParams params = mSessionParams.get(session); | 266 SessionParams params = mSessionParams.get(session); |
| 290 return params != null ? params.mShouldPrerenderOnCellular : false; | 267 return params != null ? params.mShouldPrerenderOnCellular : false; |
| 291 } | 268 } |
| 292 | 269 |
| 293 /** | 270 /** |
| 294 * Sets whether prerender should be turned on for mobile networks for given
session. | 271 * Sets whether prerender should be turned on for mobile networks for given
session. |
| 295 */ | 272 */ |
| 296 public synchronized void setPrerenderCellularForSession(IBinder session, boo
lean prerender) { | 273 public synchronized void setPrerenderCellularForSession( |
| 274 CustomTabsSessionToken session, boolean prerender) { |
| 297 SessionParams params = mSessionParams.get(session); | 275 SessionParams params = mSessionParams.get(session); |
| 298 if (params != null) params.mShouldPrerenderOnCellular = prerender; | 276 if (params != null) params.mShouldPrerenderOnCellular = prerender; |
| 299 } | 277 } |
| 300 | 278 |
| 301 /** Tries to bind to a client to keep it alive, and returns true for success
. */ | 279 /** Tries to bind to a client to keep it alive, and returns true for success
. */ |
| 302 public synchronized boolean keepAliveForSession(IBinder session, Intent inte
nt) { | 280 public synchronized boolean keepAliveForSession(CustomTabsSessionToken sessi
on, Intent intent) { |
| 303 // When an application is bound to a service, its priority is raised to | 281 // When an application is bound to a service, its priority is raised to |
| 304 // be at least equal to the application's one. This binds to a dummy | 282 // be at least equal to the application's one. This binds to a dummy |
| 305 // service (no calls to this service are made). | 283 // service (no calls to this service are made). |
| 306 if (intent == null || intent.getComponent() == null) return false; | 284 if (intent == null || intent.getComponent() == null) return false; |
| 307 SessionParams params = mSessionParams.get(session); | 285 SessionParams params = mSessionParams.get(session); |
| 308 if (params == null) return false; | 286 if (params == null) return false; |
| 309 | 287 |
| 310 String packageName = intent.getComponent().getPackageName(); | 288 String packageName = intent.getComponent().getPackageName(); |
| 311 PackageManager pm = mContext.getApplicationContext().getPackageManager()
; | 289 PackageManager pm = mContext.getApplicationContext().getPackageManager()
; |
| 312 // Only binds to the application associated to this session. | 290 // Only binds to the application associated to this session. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 327 try { | 305 try { |
| 328 ok = mContext.bindService(serviceIntent, connection, Context.BIND_AU
TO_CREATE); | 306 ok = mContext.bindService(serviceIntent, connection, Context.BIND_AU
TO_CREATE); |
| 329 } catch (SecurityException e) { | 307 } catch (SecurityException e) { |
| 330 return false; | 308 return false; |
| 331 } | 309 } |
| 332 if (ok) params.setKeepAliveConnection(connection); | 310 if (ok) params.setKeepAliveConnection(connection); |
| 333 return ok; | 311 return ok; |
| 334 } | 312 } |
| 335 | 313 |
| 336 /** Unbind from the KeepAlive service for a client. */ | 314 /** Unbind from the KeepAlive service for a client. */ |
| 337 public synchronized void dontKeepAliveForSession(IBinder session) { | 315 public synchronized void dontKeepAliveForSession(CustomTabsSessionToken sess
ion) { |
| 338 SessionParams params = mSessionParams.get(session); | 316 SessionParams params = mSessionParams.get(session); |
| 339 if (params == null || params.getKeepAliveConnection() == null) return; | 317 if (params == null || params.getKeepAliveConnection() == null) return; |
| 340 ServiceConnection connection = params.getKeepAliveConnection(); | 318 ServiceConnection connection = params.getKeepAliveConnection(); |
| 341 params.setKeepAliveConnection(null); | 319 params.setKeepAliveConnection(null); |
| 342 mContext.unbindService(connection); | 320 mContext.unbindService(connection); |
| 343 } | 321 } |
| 344 | 322 |
| 345 /** See {@link RequestThrottler#isPrerenderingAllowed()} */ | 323 /** See {@link RequestThrottler#isPrerenderingAllowed()} */ |
| 346 public synchronized boolean isPrerenderingAllowed(int uid) { | 324 public synchronized boolean isPrerenderingAllowed(int uid) { |
| 347 return RequestThrottler.getForUid(mContext, uid).isPrerenderingAllowed()
; | 325 return RequestThrottler.getForUid(mContext, uid).isPrerenderingAllowed()
; |
| 348 } | 326 } |
| 349 | 327 |
| 350 /** See {@link RequestThrottler#registerPrerenderRequest(String)} */ | 328 /** See {@link RequestThrottler#registerPrerenderRequest(String)} */ |
| 351 public synchronized void registerPrerenderRequest(int uid, String url) { | 329 public synchronized void registerPrerenderRequest(int uid, String url) { |
| 352 RequestThrottler.getForUid(mContext, uid).registerPrerenderRequest(url); | 330 RequestThrottler.getForUid(mContext, uid).registerPrerenderRequest(url); |
| 353 } | 331 } |
| 354 | 332 |
| 355 /** See {@link RequestThrottler#reset()} */ | 333 /** See {@link RequestThrottler#reset()} */ |
| 356 public synchronized void resetThrottling(int uid) { | 334 public synchronized void resetThrottling(int uid) { |
| 357 RequestThrottler.getForUid(mContext, uid).reset(); | 335 RequestThrottler.getForUid(mContext, uid).reset(); |
| 358 } | 336 } |
| 359 | 337 |
| 360 /** | 338 /** |
| 361 * Cleans up all data associated with all sessions. | 339 * Cleans up all data associated with all sessions. |
| 362 */ | 340 */ |
| 363 public synchronized void cleanupAll() { | 341 public synchronized void cleanupAll() { |
| 364 List<IBinder> sessions = new ArrayList<>(mSessionParams.keySet()); | 342 List<CustomTabsSessionToken> sessions = new ArrayList<>(mSessionParams.k
eySet()); |
| 365 for (IBinder session : sessions) cleanupSession(session); | 343 for (CustomTabsSessionToken session : sessions) cleanupSession(session); |
| 366 } | 344 } |
| 367 | 345 |
| 368 private synchronized void cleanupSession(IBinder session) { | 346 /** |
| 347 * Handle any clean up left after a session is destroyed. |
| 348 * @param session The session that has been destroyed. |
| 349 */ |
| 350 public synchronized void cleanupSession(CustomTabsSessionToken session) { |
| 369 SessionParams params = mSessionParams.get(session); | 351 SessionParams params = mSessionParams.get(session); |
| 370 if (params == null) return; | 352 if (params == null) return; |
| 371 mSessionParams.remove(session); | 353 mSessionParams.remove(session); |
| 354 if (params.disconnectCallback != null) params.disconnectCallback.run(ses
sion); |
| 372 mUidHasCalledWarmup.delete(params.uid); | 355 mUidHasCalledWarmup.delete(params.uid); |
| 373 IBinder binder = params.callback.asBinder(); | |
| 374 binder.unlinkToDeath(params.deathRecipient, 0); | |
| 375 } | 356 } |
| 376 } | 357 } |
| OLD | NEW |