Merge "Implement system API for monitoring uid importance changes."
This commit is contained in:
committed by
Android (Google) Code Review
commit
cdb31d2ecd
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Canvas;
|
||||
@@ -61,6 +62,7 @@ import android.os.ServiceManager;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Singleton;
|
||||
import android.util.Size;
|
||||
@@ -87,6 +89,49 @@ public class ActivityManager {
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
|
||||
static final class UidObserver extends IUidObserver.Stub {
|
||||
final OnUidImportanceListener mListener;
|
||||
final int mImportanceCutpoint;
|
||||
int mLastImportance;
|
||||
|
||||
UidObserver(OnUidImportanceListener listener, int importanceCutpoint) {
|
||||
mListener = listener;
|
||||
mImportanceCutpoint = importanceCutpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidStateChanged(int uid, int procState) {
|
||||
final boolean lastAboveCut = mLastImportance <= mImportanceCutpoint;
|
||||
final int importance = RunningAppProcessInfo.procStateToImportance(procState);
|
||||
final boolean newAboveCut = importance <= mImportanceCutpoint;
|
||||
/*
|
||||
Log.d(TAG, "Uid " + uid + " state change from " + mLastImportance + " to "
|
||||
+ importance + " @ cut " + mImportanceCutpoint
|
||||
+ ": lastAbove=" + lastAboveCut + " newAbove=" + newAboveCut);
|
||||
*/
|
||||
mLastImportance = importance;
|
||||
if (lastAboveCut != newAboveCut) {
|
||||
mListener.onUidImportance(uid, importance);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidGone(int uid) {
|
||||
mLastImportance = RunningAppProcessInfo.IMPORTANCE_GONE;
|
||||
mListener.onUidImportance(uid, RunningAppProcessInfo.IMPORTANCE_GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidActive(int uid) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidIdle(int uid) {
|
||||
}
|
||||
}
|
||||
|
||||
final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>();
|
||||
|
||||
/**
|
||||
* Defines acceptable types of bugreports.
|
||||
* @hide
|
||||
@@ -3045,11 +3090,11 @@ public class ActivityManager {
|
||||
* running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@SystemApi @TestApi
|
||||
@RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
|
||||
public int getPackageImportance(String packageName) {
|
||||
try {
|
||||
int procState = ActivityManagerNative.getDefault().getPackageProcessState(packageName,
|
||||
int procState = getService().getPackageProcessState(packageName,
|
||||
mContext.getOpPackageName());
|
||||
return RunningAppProcessInfo.procStateToImportance(procState);
|
||||
} catch (RemoteException e) {
|
||||
@@ -3057,6 +3102,83 @@ public class ActivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to get reports about changes to the importance of a uid. Use with
|
||||
* {@link #addOnUidImportanceListener}.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi @TestApi
|
||||
public interface OnUidImportanceListener {
|
||||
/**
|
||||
* The importance if a given uid has changed. Will be one of the importance
|
||||
* values in {@link RunningAppProcessInfo};
|
||||
* {@link RunningAppProcessInfo#IMPORTANCE_GONE IMPORTANCE_GONE} will be reported
|
||||
* when the uid is no longer running at all. This callback will happen on a thread
|
||||
* from a thread pool, not the main UI thread.
|
||||
* @param uid The uid whose importance has changed.
|
||||
* @param importance The new importance value as per {@link RunningAppProcessInfo}.
|
||||
*/
|
||||
void onUidImportance(int uid, int importance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start monitoring changes to the imoportance of uids running in the system.
|
||||
* @param listener The listener callback that will receive change reports.
|
||||
* @param importanceCutpoint The level of importance in which the caller is interested
|
||||
* in differences. For example, if {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE}
|
||||
* is used here, you will receive a call each time a uids importance transitions between
|
||||
* being <= {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE} and
|
||||
* > {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE}.
|
||||
*
|
||||
* <p>The caller must hold the {@link android.Manifest.permission#PACKAGE_USAGE_STATS}
|
||||
* permission to use this feature.</p>
|
||||
*
|
||||
* @throws IllegalArgumentException If the listener is already registered.
|
||||
* @throws SecurityException If the caller does not hold
|
||||
* {@link android.Manifest.permission#PACKAGE_USAGE_STATS}.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi @TestApi
|
||||
public void addOnUidImportanceListener(OnUidImportanceListener listener,
|
||||
int importanceCutpoint) {
|
||||
synchronized (this) {
|
||||
if (mImportanceListeners.containsKey(listener)) {
|
||||
throw new IllegalArgumentException("Listener already registered: " + listener);
|
||||
}
|
||||
// TODO: implement the cut point in the system process to avoid IPCs.
|
||||
UidObserver observer = new UidObserver(listener, importanceCutpoint);
|
||||
try {
|
||||
getService().registerUidObserver(observer,
|
||||
UID_OBSERVER_PROCSTATE | UID_OBSERVER_GONE, mContext.getOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
mImportanceListeners.put(listener, observer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an importance listener that was previously registered with
|
||||
* {@link #addOnUidImportanceListener}.
|
||||
*
|
||||
* @throws IllegalArgumentException If the listener is not registered.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi @TestApi
|
||||
public void removeOnUidImportanceListener(OnUidImportanceListener listener) {
|
||||
synchronized (this) {
|
||||
UidObserver observer = mImportanceListeners.remove(listener);
|
||||
if (observer == null) {
|
||||
throw new IllegalArgumentException("Listener not registered: " + listener);
|
||||
}
|
||||
try {
|
||||
getService().unregisterUidObserver(observer);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return global memory state information for the calling process. This
|
||||
* does not fill in all fields of the {@link RunningAppProcessInfo}. The
|
||||
|
||||
@@ -431,7 +431,7 @@ interface IActivityManager {
|
||||
* etc.
|
||||
*/
|
||||
void keyguardGoingAway(int flags) = 296;
|
||||
void registerUidObserver(in IUidObserver observer, int which) = 297;
|
||||
void registerUidObserver(in IUidObserver observer, int which, String callingPackage) = 297;
|
||||
void unregisterUidObserver(in IUidObserver observer) = 298;
|
||||
boolean isAssistDataAllowedOnCurrentActivity() = 299;
|
||||
boolean showAssistFromActivity(in IBinder token, in Bundle args) = 300;
|
||||
|
||||
Reference in New Issue
Block a user