Chromium Code Reviews| 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; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 @VisibleForTesting static final int NO_SESSION_NO_WARMUP = 0; | 52 @VisibleForTesting static final int NO_SESSION_NO_WARMUP = 0; |
| 53 @VisibleForTesting static final int NO_SESSION_WARMUP = 1; | 53 @VisibleForTesting static final int NO_SESSION_WARMUP = 1; |
| 54 @VisibleForTesting static final int SESSION_NO_WARMUP_ALREADY_CALLED = 2; | 54 @VisibleForTesting static final int SESSION_NO_WARMUP_ALREADY_CALLED = 2; |
| 55 @VisibleForTesting static final int SESSION_NO_WARMUP_NOT_CALLED = 3; | 55 @VisibleForTesting static final int SESSION_NO_WARMUP_NOT_CALLED = 3; |
| 56 @VisibleForTesting static final int SESSION_WARMUP = 4; | 56 @VisibleForTesting static final int SESSION_WARMUP = 4; |
| 57 @VisibleForTesting static final int SESSION_WARMUP_COUNT = 5; | 57 @VisibleForTesting static final int SESSION_WARMUP_COUNT = 5; |
| 58 | 58 |
| 59 /** To be called when a client gets disconnected. */ | 59 /** To be called when a client gets disconnected. */ |
| 60 public interface DisconnectCallback { public void run(CustomTabsSessionToken session); } | 60 public interface DisconnectCallback { public void run(CustomTabsSessionToken session); } |
| 61 | 61 |
| 62 private static class KeepAliveServiceConnection implements ServiceConnection { | |
| 63 private final Context mContext; | |
| 64 private final Intent mServiceIntent; | |
| 65 private boolean mHasDied; | |
| 66 private boolean mIsBound; | |
| 67 | |
| 68 public KeepAliveServiceConnection(Context context, Intent serviceIntent) { | |
| 69 mContext = context; | |
| 70 mServiceIntent = serviceIntent; | |
| 71 } | |
| 72 | |
|
Yusuf
2017/02/15 17:43:52
javadoc
Benoit L
2017/02/16 10:25:52
Done.
| |
| 73 public boolean connect() { | |
| 74 if (mIsBound) return true; | |
| 75 // If the remote process died at some point, it doesn't make sense t o resurrect it. | |
| 76 if (mHasDied) return false; | |
| 77 | |
| 78 boolean ok; | |
| 79 try { | |
| 80 ok = mContext.bindService(mServiceIntent, this, Context.BIND_AUT O_CREATE); | |
| 81 } catch (SecurityException e) { | |
| 82 return false; | |
| 83 } | |
| 84 mIsBound = ok; | |
| 85 return ok; | |
| 86 } | |
| 87 | |
|
Yusuf
2017/02/15 17:43:52
javadoc
Benoit L
2017/02/16 10:25:52
Done.
| |
| 88 public void disconnect() { | |
| 89 if (mIsBound) { | |
| 90 mContext.unbindService(this); | |
|
Yusuf
2017/02/15 17:43:51
Will unbind still work if we are disconnected? Whe
Benoit L
2017/02/16 10:25:52
Yes, but you cannot unbind twice, otherwise the fr
| |
| 91 mIsBound = false; | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 @Override | |
| 96 public void onServiceConnected(ComponentName name, IBinder service) {} | |
| 97 | |
| 98 @Override | |
| 99 public void onServiceDisconnected(ComponentName name) { | |
| 100 if (mIsBound) { | |
| 101 // The remote process has died. This typically happens if the sy stem is low enough | |
| 102 // on memory to kill one of the last process on the "kill list". In this case, we | |
| 103 // shouldn't resurrect the process (which happens with BIND_AUTO _CREATE) because | |
| 104 // that could create a "restart/kill" loop. | |
| 105 mHasDied = true; | |
| 106 disconnect(); | |
| 107 } | |
| 108 } | |
| 109 } | |
| 110 | |
| 62 /** Per-session values. */ | 111 /** Per-session values. */ |
| 63 private static class SessionParams { | 112 private static class SessionParams { |
| 64 public final int uid; | 113 public final int uid; |
| 65 public final DisconnectCallback disconnectCallback; | 114 public final DisconnectCallback disconnectCallback; |
| 66 public final String packageName; | 115 public final String packageName; |
| 67 public final PostMessageHandler postMessageHandler; | 116 public final PostMessageHandler postMessageHandler; |
| 68 public boolean mIgnoreFragments; | 117 public boolean mIgnoreFragments; |
| 69 public boolean lowConfidencePrediction; | 118 public boolean lowConfidencePrediction; |
| 70 public boolean highConfidencePrediction; | 119 public boolean highConfidencePrediction; |
| 71 private boolean mShouldHideDomain; | 120 private boolean mShouldHideDomain; |
| 72 private boolean mShouldPrerenderOnCellular; | 121 private boolean mShouldPrerenderOnCellular; |
| 73 private boolean mShouldSendNavigationInfo; | 122 private boolean mShouldSendNavigationInfo; |
| 74 private ServiceConnection mKeepAliveConnection; | 123 private KeepAliveServiceConnection mKeepAliveConnection; |
| 75 private String mPredictedUrl; | 124 private String mPredictedUrl; |
| 76 private long mLastMayLaunchUrlTimestamp; | 125 private long mLastMayLaunchUrlTimestamp; |
| 77 | 126 |
| 78 public SessionParams(Context context, int uid, DisconnectCallback callba ck, | 127 public SessionParams(Context context, int uid, DisconnectCallback callba ck, |
| 79 PostMessageHandler postMessageHandler) { | 128 PostMessageHandler postMessageHandler) { |
| 80 this.uid = uid; | 129 this.uid = uid; |
| 81 packageName = getPackageName(context, uid); | 130 packageName = getPackageName(context, uid); |
| 82 disconnectCallback = callback; | 131 disconnectCallback = callback; |
| 83 this.postMessageHandler = postMessageHandler; | 132 this.postMessageHandler = postMessageHandler; |
| 84 } | 133 } |
| 85 | 134 |
| 86 private static String getPackageName(Context context, int uid) { | 135 private static String getPackageName(Context context, int uid) { |
| 87 PackageManager packageManager = context.getPackageManager(); | 136 PackageManager packageManager = context.getPackageManager(); |
| 88 String[] packageList = packageManager.getPackagesForUid(uid); | 137 String[] packageList = packageManager.getPackagesForUid(uid); |
| 89 if (packageList.length != 1 || TextUtils.isEmpty(packageList[0])) re turn null; | 138 if (packageList.length != 1 || TextUtils.isEmpty(packageList[0])) re turn null; |
| 90 return packageList[0]; | 139 return packageList[0]; |
| 91 } | 140 } |
| 92 | 141 |
| 93 public ServiceConnection getKeepAliveConnection() { | 142 public KeepAliveServiceConnection getKeepAliveConnection() { |
| 94 return mKeepAliveConnection; | 143 return mKeepAliveConnection; |
| 95 } | 144 } |
| 96 | 145 |
| 97 public void setKeepAliveConnection(ServiceConnection serviceConnection) { | 146 public void setKeepAliveConnection(KeepAliveServiceConnection serviceCon nection) { |
| 98 mKeepAliveConnection = serviceConnection; | 147 mKeepAliveConnection = serviceConnection; |
| 99 } | 148 } |
| 100 | 149 |
| 101 public void setPredictionMetrics( | 150 public void setPredictionMetrics( |
| 102 String predictedUrl, long lastMayLaunchUrlTimestamp, boolean low Confidence) { | 151 String predictedUrl, long lastMayLaunchUrlTimestamp, boolean low Confidence) { |
| 103 mPredictedUrl = predictedUrl; | 152 mPredictedUrl = predictedUrl; |
| 104 mLastMayLaunchUrlTimestamp = lastMayLaunchUrlTimestamp; | 153 mLastMayLaunchUrlTimestamp = lastMayLaunchUrlTimestamp; |
| 105 highConfidencePrediction |= !TextUtils.isEmpty(predictedUrl); | 154 highConfidencePrediction |= !TextUtils.isEmpty(predictedUrl); |
| 106 lowConfidencePrediction |= lowConfidence; | 155 lowConfidencePrediction |= lowConfidence; |
| 107 } | 156 } |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 | 444 |
| 396 /** Tries to bind to a client to keep it alive, and returns true for success . */ | 445 /** Tries to bind to a client to keep it alive, and returns true for success . */ |
| 397 public synchronized boolean keepAliveForSession(CustomTabsSessionToken sessi on, Intent intent) { | 446 public synchronized boolean keepAliveForSession(CustomTabsSessionToken sessi on, Intent intent) { |
| 398 // When an application is bound to a service, its priority is raised to | 447 // When an application is bound to a service, its priority is raised to |
| 399 // be at least equal to the application's one. This binds to a dummy | 448 // be at least equal to the application's one. This binds to a dummy |
| 400 // service (no calls to this service are made). | 449 // service (no calls to this service are made). |
| 401 if (intent == null || intent.getComponent() == null) return false; | 450 if (intent == null || intent.getComponent() == null) return false; |
| 402 SessionParams params = mSessionParams.get(session); | 451 SessionParams params = mSessionParams.get(session); |
| 403 if (params == null) return false; | 452 if (params == null) return false; |
| 404 | 453 |
| 405 String packageName = intent.getComponent().getPackageName(); | 454 KeepAliveServiceConnection connection = params.getKeepAliveConnection(); |
| 406 PackageManager pm = mContext.getApplicationContext().getPackageManager() ; | 455 |
| 407 // Only binds to the application associated to this session. | 456 if (connection == null) { |
| 408 if (!Arrays.asList(pm.getPackagesForUid(params.uid)).contains(packageNam e)) return false; | 457 String packageName = intent.getComponent().getPackageName(); |
| 409 Intent serviceIntent = new Intent().setComponent(intent.getComponent()); | 458 PackageManager pm = mContext.getApplicationContext().getPackageManag er(); |
| 410 // This ServiceConnection doesn't handle disconnects. This is on | 459 // Only binds to the application associated to this session. |
| 411 // purpose, as it occurs when the remote process has died. Since the | 460 if (!Arrays.asList(pm.getPackagesForUid(params.uid)).contains(packag eName)) { |
| 412 // only use of this connection is to keep the application alive, | 461 return false; |
| 413 // re-connecting would just re-create the process, but the application | 462 } |
| 414 // state has been lost at that point, the callbacks invalidated, etc. | 463 Intent serviceIntent = new Intent().setComponent(intent.getComponent ()); |
| 415 ServiceConnection connection = new ServiceConnection() { | 464 connection = new KeepAliveServiceConnection(mContext, serviceIntent) ; |
| 416 @Override | |
| 417 public void onServiceConnected(ComponentName name, IBinder service) {} | |
| 418 @Override | |
| 419 public void onServiceDisconnected(ComponentName name) {} | |
| 420 }; | |
| 421 boolean ok; | |
| 422 try { | |
| 423 ok = mContext.bindService(serviceIntent, connection, Context.BIND_AU TO_CREATE); | |
| 424 } catch (SecurityException e) { | |
| 425 return false; | |
| 426 } | 465 } |
| 466 | |
| 467 boolean ok = connection.connect(); | |
| 427 if (ok) params.setKeepAliveConnection(connection); | 468 if (ok) params.setKeepAliveConnection(connection); |
| 428 return ok; | 469 return ok; |
| 429 } | 470 } |
| 430 | 471 |
| 431 /** Unbind from the KeepAlive service for a client. */ | 472 /** Unbind from the KeepAlive service for a client. */ |
| 432 public synchronized void dontKeepAliveForSession(CustomTabsSessionToken sess ion) { | 473 public synchronized void dontKeepAliveForSession(CustomTabsSessionToken sess ion) { |
| 433 SessionParams params = mSessionParams.get(session); | 474 SessionParams params = mSessionParams.get(session); |
| 434 if (params == null || params.getKeepAliveConnection() == null) return; | 475 if (params == null || params.getKeepAliveConnection() == null) return; |
| 435 ServiceConnection connection = params.getKeepAliveConnection(); | 476 KeepAliveServiceConnection connection = params.getKeepAliveConnection(); |
| 436 params.setKeepAliveConnection(null); | 477 connection.disconnect(); |
| 437 mContext.unbindService(connection); | |
| 438 } | 478 } |
| 439 | 479 |
| 440 /** See {@link RequestThrottler#isPrerenderingAllowed()} */ | 480 /** See {@link RequestThrottler#isPrerenderingAllowed()} */ |
| 441 public synchronized boolean isPrerenderingAllowed(int uid) { | 481 public synchronized boolean isPrerenderingAllowed(int uid) { |
| 442 return RequestThrottler.getForUid(mContext, uid).isPrerenderingAllowed() ; | 482 return RequestThrottler.getForUid(mContext, uid).isPrerenderingAllowed() ; |
| 443 } | 483 } |
| 444 | 484 |
| 445 /** See {@link RequestThrottler#registerPrerenderRequest(String)} */ | 485 /** See {@link RequestThrottler#registerPrerenderRequest(String)} */ |
| 446 public synchronized void registerPrerenderRequest(int uid, String url) { | 486 public synchronized void registerPrerenderRequest(int uid, String url) { |
| 447 RequestThrottler.getForUid(mContext, uid).registerPrerenderRequest(url); | 487 RequestThrottler.getForUid(mContext, uid).registerPrerenderRequest(url); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 473 SessionParams params = mSessionParams.get(session); | 513 SessionParams params = mSessionParams.get(session); |
| 474 if (params == null) return; | 514 if (params == null) return; |
| 475 mSessionParams.remove(session); | 515 mSessionParams.remove(session); |
| 476 if (params.postMessageHandler != null) { | 516 if (params.postMessageHandler != null) { |
| 477 params.postMessageHandler.unbindFromContext(mContext); | 517 params.postMessageHandler.unbindFromContext(mContext); |
| 478 } | 518 } |
| 479 if (params.disconnectCallback != null) params.disconnectCallback.run(ses sion); | 519 if (params.disconnectCallback != null) params.disconnectCallback.run(ses sion); |
| 480 mUidHasCalledWarmup.delete(params.uid); | 520 mUidHasCalledWarmup.delete(params.uid); |
| 481 } | 521 } |
| 482 } | 522 } |
| OLD | NEW |