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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAServiceClient.java

Issue 2477513004: android: Record the memory size of the GSA process. (Closed)
Patch Set: Address comments. Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAServiceClient.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAServiceClient.java b/chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAServiceClient.java
index 688c52f1268a996ef84465233481a02cc5a1d19a..b82a90998561d7e422b5b8532f541162d7d85df6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAServiceClient.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAServiceClient.java
@@ -5,11 +5,14 @@
package org.chromium.chrome.browser.gsa;
import android.annotation.SuppressLint;
+import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -18,9 +21,15 @@ import android.os.RemoteException;
import android.util.Log;
import org.chromium.base.Callback;
+import org.chromium.base.ContextUtils;
+import org.chromium.base.TraceEvent;
+import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.browser.ChromeApplication;
+import java.util.List;
+
/**
* A simple client that connects and talks to the GSAService using Messages.
*/
@@ -31,8 +40,8 @@ public class GSAServiceClient {
* Constants for gsa communication. These should not change without corresponding changes on the
* service side in GSA.
*/
- private static final String GSA_SERVICE =
- "com.google.android.ssb.action.SSB_SERVICE";
+ @VisibleForTesting
+ static final String GSA_SERVICE = "com.google.android.ssb.action.SSB_SERVICE";
public static final int REQUEST_REGISTER_CLIENT = 2;
public static final int RESPONSE_UPDATE_SSB = 3;
@@ -40,6 +49,10 @@ public class GSAServiceClient {
public static final String KEY_GSA_CONTEXT = "ssb_service:ssb_context";
public static final String KEY_GSA_PACKAGE_NAME = "ssb_service:ssb_package_name";
+ @VisibleForTesting
+ static final int INVALID_PSS = -1;
+
+ private static boolean sHasRecordedPss;
/** Messenger to handle incoming messages from the service */
private final Messenger mMessenger;
private final IncomingHandler mHandler;
@@ -50,7 +63,7 @@ public class GSAServiceClient {
/** Messenger for communicating with service. */
private Messenger mService;
-
+ private ComponentName mComponentName;
/**
* Handler of incoming messages from service.
@@ -60,17 +73,85 @@ public class GSAServiceClient {
private class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
- if (msg.what == RESPONSE_UPDATE_SSB) {
- if (mService == null) return;
- Bundle bundle = (Bundle) msg.obj;
- String account =
- mGsaHelper.getGSAAccountFromState(bundle.getByteArray(KEY_GSA_STATE));
- GSAState.getInstance(mContext.getApplicationContext()).setGsaAccount(account);
- if (mOnMessageReceived != null) mOnMessageReceived.onResult(bundle);
- } else {
+ if (msg.what != RESPONSE_UPDATE_SSB) {
super.handleMessage(msg);
+ return;
+ }
+
+ if (mService == null) return;
+ final Bundle bundle = (Bundle) msg.obj;
+ String account = mGsaHelper.getGSAAccountFromState(bundle.getByteArray(KEY_GSA_STATE));
+ GSAState.getInstance(mContext.getApplicationContext()).setGsaAccount(account);
+ if (sHasRecordedPss) {
+ if (mOnMessageReceived != null) mOnMessageReceived.onResult(bundle);
+ return;
+ }
+
+ // Getting the PSS for the GSA service process can be long, don't block the UI thread on
+ // that. Also, don't process the callback before the PSS is known, since the callback
+ // can lead to a service disconnect, which can lead to the framework killing the
+ // process. Hence an AsyncTask (long operation), and processing the callback in
+ // onPostExecute() (don't disconnect before).
+ sHasRecordedPss = true;
+ new AsyncTask<Void, Void, Integer>() {
+ @Override
+ protected Integer doInBackground(Void... params) {
+ TraceEvent.begin("GSAServiceClient.getPssForservice");
+ try {
+ // Looking for the service process is done by component name, which is
+ // inefficient. We really want the PID, which is only accessible from within
+ // a Binder transaction. Since the service connection is Messenger-based,
+ // the calls are not processed from a Binder thread. The alternatives are:
+ // 1. Override methods in the framework to append the calling PID to the
+ // Message.
+ // 2. Usse msg.callingUid to narrow down the search.
+ //
+ // (1) is dirty (and brittle), and (2) only works on L+, and still requires
+ // to get the full list of services from ActivityManager.
+ return getPssForService(mComponentName);
+ } finally {
+ TraceEvent.end("GSAServiceClient.getPssForservice");
+ }
+ }
+
+ @Override
+ protected void onPostExecute(Integer pssInKB) {
+ if (pssInKB != INVALID_PSS) {
+ RecordHistogram.recordMemoryKBHistogram(
+ "Search.GsaProcessMemoryPss", pssInKB);
+ }
+ if (mOnMessageReceived != null) mOnMessageReceived.onResult(bundle);
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ }
+
+ /**
+ * Get the PSS used by the process hosting a service.
+ *
+ * @param packageName Package name of the service to search for.
+ * @return the PSS in kB of the process hosting a service, or INVALID_PSS.
+ */
+ @VisibleForTesting
+ static int getPssForService(ComponentName componentName) {
+ if (componentName == null) return INVALID_PSS;
+ Context context = ContextUtils.getApplicationContext();
+ ActivityManager activityManager =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ List<ActivityManager.RunningServiceInfo> services =
+ activityManager.getRunningServices(1000);
+ if (services == null) return INVALID_PSS;
+ int pid = -1;
+ for (ActivityManager.RunningServiceInfo info : services) {
+ if (componentName.equals(info.service)) {
+ pid = info.pid;
+ break;
}
}
+ if (pid == -1) return INVALID_PSS;
+ Debug.MemoryInfo infos[] = activityManager.getProcessMemoryInfo(new int[] {pid});
+ if (infos == null || infos.length == 0) return INVALID_PSS;
+ return infos[0].getTotalPss();
}
/**
@@ -137,6 +218,7 @@ public class GSAServiceClient {
if (mContext == null) return;
mService = new Messenger(service);
+ mComponentName = name;
try {
Message registerClientMessage = Message.obtain(
null, REQUEST_REGISTER_CLIENT);
« no previous file with comments | « base/android/java/src/org/chromium/base/metrics/RecordHistogram.java ('k') | chrome/android/java_sources.gni » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698