Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java

Issue 2679933004: customtabs: Don't resurrect a "kept alive" process that died. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698