Merge "Allow EJs to obtain new network capability." into sc-dev am: 8632838c50

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13526199

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I49e2e51958d6e8dfe75d9c0dca66a7dc362b16ac
This commit is contained in:
Sudheer Shanka
2021-02-25 09:40:05 +00:00
committed by Automerger Merge Worker
11 changed files with 170 additions and 17 deletions

View File

@@ -271,7 +271,9 @@ public final class JobServiceContext implements ServiceConnection {
if (job.shouldTreatAsExpeditedJob()) {
// TODO(171305774): The job should run on the little cores. We'll probably need
// another binding flag for that.
bindFlags = Context.BIND_AUTO_CREATE;
bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
| Context.BIND_ALMOST_PERCEPTIBLE
| Context.BIND_ALLOW_NETWORK_ACCESS;
} else {
bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
| Context.BIND_NOT_PERCEPTIBLE;

View File

@@ -91,6 +91,8 @@ package android.app {
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener);
method public void alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName);
method public long getTotalRam();
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidProcessCapabilities(int);
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidProcessState(int);
method public void holdLock(android.os.IBinder, int);
method public static boolean isHighEndGfx();
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void removeHomeVisibilityListener(@NonNull android.app.HomeVisibilityListener);
@@ -106,7 +108,10 @@ package android.app {
field public static final int PROCESS_CAPABILITY_FOREGROUND_CAMERA = 2; // 0x2
field public static final int PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1; // 0x1
field public static final int PROCESS_CAPABILITY_FOREGROUND_MICROPHONE = 4; // 0x4
field public static final int PROCESS_CAPABILITY_NETWORK = 8; // 0x8
field public static final int PROCESS_CAPABILITY_NONE = 0; // 0x0
field public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; // 0x4
field public static final int PROCESS_STATE_TOP = 2; // 0x2
}
public static class ActivityManager.RunningAppProcessInfo implements android.os.Parcelable {

View File

@@ -511,6 +511,7 @@ public class ActivityManager {
/** @hide Process is hosting the current top activities. Note that this covers
* all activities that are visible to the user. */
@UnsupportedAppUsage
@TestApi
public static final int PROCESS_STATE_TOP = ProcessStateEnum.TOP;
/** @hide Process is bound to a TOP app. */
@@ -518,6 +519,7 @@ public class ActivityManager {
/** @hide Process is hosting a foreground service. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@TestApi
public static final int PROCESS_STATE_FOREGROUND_SERVICE = ProcessStateEnum.FOREGROUND_SERVICE;
/** @hide Process is hosting a foreground service due to a system binding. */
@@ -617,6 +619,7 @@ public class ActivityManager {
public static final int PROCESS_CAPABILITY_FOREGROUND_MICROPHONE = 1 << 2;
/** @hide Process can access network despite any power saving resrictions */
@TestApi
public static final int PROCESS_CAPABILITY_NETWORK = 1 << 3;
/** @hide all capabilities, the ORing of all flags in {@link ProcessCapability}*/
@@ -3431,6 +3434,36 @@ public class ActivityManager {
return SystemProperties.getBoolean("persist.sys.lmk.reportkills", false);
}
/**
* Returns the process state of this uid.
*
* @hide
*/
@TestApi
@RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
public int getUidProcessState(int uid) {
try {
return getService().getUidProcessState(uid, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the process capability of this uid.
*
* @hide
*/
@TestApi
@RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
public @ProcessCapability int getUidProcessCapabilities(int uid) {
try {
return getService().getUidProcessCapabilities(uid, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Return the importance of a given package name, based on the processes that are
* currently running. The return value is one of the importance constants defined

View File

@@ -707,4 +707,6 @@ interface IActivityManager {
/** Called by PendingIntent.queryIntentComponents() */
List<ResolveInfo> queryIntentComponentsForIntentSender(in IIntentSender sender, int matchFlags);
int getUidProcessCapabilities(int uid, in String callingPackage);
}

View File

@@ -369,6 +369,25 @@ public abstract class Context {
/*********** Public flags above this line ***********/
/*********** Hidden flags below this line ***********/
/**
* Flag for {@link #bindService}: allow the process hosting the target service to be treated
* as if it's as important as a perceptible app to the user and avoid the oom killer killing
* this process in low memory situations until there aren't any other processes left but the
* ones which are user-perceptible.
*
* @hide
*/
public static final int BIND_ALMOST_PERCEPTIBLE = 0x000010000;
/**
* Flag for {@link #bindService}: allow the process hosting the target service to gain
* {@link ActivityManager#PROCESS_CAPABILITY_NETWORK}, which allows it be able
* to access network regardless of any power saving restrictions.
*
* @hide
*/
public static final int BIND_ALLOW_NETWORK_ACCESS = 0x00020000;
/**
* Flag for {@link #bindService}: allow background foreground service starts from the bound
* service's process.

View File

@@ -143,6 +143,7 @@ import android.app.Activity;
import android.app.ActivityClient;
import android.app.ActivityManager;
import android.app.ActivityManager.PendingIntentInfo;
import android.app.ActivityManager.ProcessCapability;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManagerInternal;
import android.app.ActivityTaskManager.RootTaskInfo;
@@ -6585,6 +6586,18 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
@Override
public @ProcessCapability int getUidProcessCapabilities(int uid, String callingPackage) {
if (!hasUsageStatsPermission(callingPackage)) {
enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
"getUidProcessState");
}
synchronized (mProcLock) {
return mProcessList.getUidProcessCapabilityLOSP(uid);
}
}
@Override
public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
String callingPackage) {
@@ -10031,6 +10044,7 @@ public class ActivityManagerService extends IActivityManager.Stub
ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
ProcessList.VISIBLE_APP_ADJ,
ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_LOW_APP_ADJ,
ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ,
ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
@@ -10038,7 +10052,7 @@ public class ActivityManagerService extends IActivityManager.Stub
static final String[] DUMP_MEM_OOM_LABEL = new String[] {
"Native",
"System", "Persistent", "Persistent Service", "Foreground",
"Visible", "Perceptible", "Perceptible Low",
"Visible", "Perceptible", "Perceptible Low", "Perceptible Medium",
"Heavy Weight", "Backup",
"A Services", "Home",
"Previous", "B Services", "Cached"
@@ -10046,7 +10060,7 @@ public class ActivityManagerService extends IActivityManager.Stub
static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
"native",
"sys", "pers", "persvc", "fore",
"vis", "percept", "perceptl",
"vis", "percept", "perceptl", "perceptm",
"heavy", "backup",
"servicea", "home",
"prev", "serviceb", "cached"
@@ -13904,7 +13918,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
void noteUidProcessState(final int uid, final int state,
final @ActivityManager.ProcessCapability int capability) {
final @ProcessCapability int capability) {
mBatteryStatsService.noteUidProcessState(uid, state);
mAppOpsService.updateUidProcState(uid, state, capability);
if (mTrackingAssociations) {

View File

@@ -21,6 +21,7 @@ import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
@@ -1981,6 +1982,21 @@ public final class OomAdjuster {
capability |= cstate.getCurCapability();
}
// If an app has network capability by default
// (by having procstate <= BFGS), then the apps it binds to will get
// elevated to a high enough procstate anyway to get network unless they
// request otherwise, so don't propagate the network capability by default
// in this case unless they explicitly request it.
if ((cstate.getCurCapability() & PROCESS_CAPABILITY_NETWORK) != 0) {
if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
if ((cr.flags & Context.BIND_ALLOW_NETWORK_ACCESS) != 0) {
capability |= PROCESS_CAPABILITY_NETWORK;
}
} else {
capability |= PROCESS_CAPABILITY_NETWORK;
}
}
if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
// If the other app is cached for any reason, for purposes here
// we are going to consider it empty. The specific cached state
@@ -2048,6 +2064,10 @@ public final class OomAdjuster {
&& clientAdj <= ProcessList.PERCEPTIBLE_APP_ADJ
&& adj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
newAdj = ProcessList.PERCEPTIBLE_LOW_APP_ADJ;
} else if ((cr.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0
&& clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
&& adj >= ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ) {
newAdj = ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ;
} else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
&& clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
&& adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -2117,13 +2137,13 @@ public final class OomAdjuster {
if (enabled) {
if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
// TOP process passes all capabilities to the service.
capability |= PROCESS_CAPABILITY_ALL;
capability |= cstate.getCurCapability();
} else {
// TOP process passes no capability to the service.
}
} else {
// TOP process passes all capabilities to the service.
capability |= PROCESS_CAPABILITY_ALL;
capability |= cstate.getCurCapability();
}
}
} else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
@@ -2448,20 +2468,20 @@ public final class OomAdjuster {
case PROCESS_STATE_TOP:
return PROCESS_CAPABILITY_ALL;
case PROCESS_STATE_BOUND_TOP:
return PROCESS_CAPABILITY_NONE;
return PROCESS_CAPABILITY_NETWORK;
case PROCESS_STATE_FOREGROUND_SERVICE:
if (psr.hasForegroundServices()) {
// Capability from FGS are conditional depending on foreground service type in
// manifest file and the mAllowWhileInUsePermissionInFgs flag.
return PROCESS_CAPABILITY_NONE;
return PROCESS_CAPABILITY_NETWORK;
} else {
// process has no FGS, the PROCESS_STATE_FOREGROUND_SERVICE is from client.
// the implicit capability could be removed in the future, client should use
// BIND_INCLUDE_CAPABILITY flag.
return PROCESS_CAPABILITY_ALL_IMPLICIT;
return PROCESS_CAPABILITY_ALL_IMPLICIT | PROCESS_CAPABILITY_NETWORK;
}
case PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
return PROCESS_CAPABILITY_NONE;
return PROCESS_CAPABILITY_NETWORK;
default:
return PROCESS_CAPABILITY_NONE;
}

View File

@@ -16,6 +16,7 @@
package com.android.server.am;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
@@ -57,6 +58,7 @@ import static com.android.server.am.AppProfiler.TAG_PSS;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManager.ProcessCapability;
import android.app.ActivityThread;
import android.app.AppGlobals;
import android.app.AppProtoEnums;
@@ -228,6 +230,11 @@ public final class ProcessList {
// not so perceptible that it affects the user immediately if killed.
static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
// This is a process hosting services that are not perceptible to the user but the
// client (system) binding to it requested to treat it as if it is perceptible and avoid killing
// it if possible.
static final int PERCEPTIBLE_MEDIUM_APP_ADJ = 225;
// This is a process only hosting components that are perceptible to the
// user, and we really want to avoid killing them, but they are not
// immediately visible. An example is background music playback.
@@ -1027,6 +1034,9 @@ public final class ProcessList {
} else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
return buildOomTag("prcl ", "prcl", null, setAdj,
ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact);
} else if (setAdj >= ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ) {
return buildOomTag("prcm ", "prcm", null, setAdj,
ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ, compact);
} else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
return buildOomTag("prcp ", "prcp", null, setAdj,
ProcessList.PERCEPTIBLE_APP_ADJ, compact);
@@ -4395,6 +4405,7 @@ public final class ProcessList {
printOomLevel(pw, "FOREGROUND_APP_ADJ", FOREGROUND_APP_ADJ);
printOomLevel(pw, "VISIBLE_APP_ADJ", VISIBLE_APP_ADJ);
printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", PERCEPTIBLE_APP_ADJ);
printOomLevel(pw, "PERCEPTIBLE_MEDIUM_APP_ADJ", PERCEPTIBLE_MEDIUM_APP_ADJ);
printOomLevel(pw, "PERCEPTIBLE_LOW_APP_ADJ", PERCEPTIBLE_LOW_APP_ADJ);
printOomLevel(pw, "BACKUP_APP_ADJ", BACKUP_APP_ADJ);
printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", HEAVY_WEIGHT_APP_ADJ);
@@ -4658,13 +4669,26 @@ public final class ProcessList {
}
}
/** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
/**
* Returns the uid's process state or {@link ActivityManager#PROCESS_STATE_NONEXISTENT}
* if not running
*/
@GuardedBy(anyOf = {"mService", "mProcLock"})
int getUidProcStateLOSP(int uid) {
UidRecord uidRec = mActiveUids.get(uid);
return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
}
/**
* Returns the uid's process capability or {@link ActivityManager#PROCESS_CAPABILITY_NONE}
* if not running
*/
@GuardedBy(anyOf = {"mService", "mProcLock"})
@ProcessCapability int getUidProcessCapabilityLOSP(int uid) {
UidRecord uidRec = mActiveUids.get(uid);
return uidRec == null ? PROCESS_CAPABILITY_NONE : uidRec.getCurCapability();
}
/** Returns the UidRecord for the given uid, if it exists. */
@GuardedBy(anyOf = {"mService", "mProcLock"})
UidRecord getUidRecordLOSP(int uid) {
@@ -4749,8 +4773,9 @@ public final class ProcessList {
if (!UserHandle.isApp(uidRec.getUid()) || !uidRec.hasInternetPermission) {
continue;
}
// If process state is not changed, then there's nothing to do.
if (uidRec.getSetProcState() == uidRec.getCurProcState()) {
// If process state and capabilities are not changed, then there's nothing to do.
if (uidRec.getSetProcState() == uidRec.getCurProcState()
&& uidRec.getSetCapability() == uidRec.getCurCapability()) {
continue;
}
final int blockState = getBlockStateForUid(uidRec);

View File

@@ -882,9 +882,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
try {
// TODO: There shouldn't be a need to receive callback for all changes.
mActivityManager.registerUidObserver(mUidObserver,
ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android");
ActivityManager.PROCESS_STATE_UNKNOWN, "android");
mNetworkManager.registerObserver(mAlertObserver);
} catch (RemoteException e) {
// ignored; both services live in system_server

View File

@@ -46,6 +46,7 @@ import static com.android.server.am.ProcessList.HEAVY_WEIGHT_APP_ADJ;
import static com.android.server.am.ProcessList.HOME_APP_ADJ;
import static com.android.server.am.ProcessList.PERCEPTIBLE_APP_ADJ;
import static com.android.server.am.ProcessList.PERCEPTIBLE_LOW_APP_ADJ;
import static com.android.server.am.ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ;
import static com.android.server.am.ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
import static com.android.server.am.ProcessList.PERSISTENT_PROC_ADJ;
import static com.android.server.am.ProcessList.PERSISTENT_SERVICE_ADJ;
@@ -875,6 +876,39 @@ public class MockingOomAdjusterTests {
assertEquals(PERCEPTIBLE_APP_ADJ, app.mState.getSetAdj());
}
@SuppressWarnings("GuardedBy")
@Test
public void testUpdateOomAdj_DoOne_Service_MediumPerceptible() {
{
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
bindService(app, client, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class));
client.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, false, OomAdjuster.OOM_ADJ_REASON_NONE);
assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ, app.mState.getSetAdj());
}
{
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
WindowProcessController wpc = client.getWindowProcessController();
doReturn(true).when(wpc).isHeavyWeightProcess();
bindService(app, client, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class));
client.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, false, OomAdjuster.OOM_ADJ_REASON_NONE);
doReturn(false).when(wpc).isHeavyWeightProcess();
assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ, app.mState.getSetAdj());
}
}
@SuppressWarnings("GuardedBy")
@Test
public void testUpdateOomAdj_DoOne_Service_Other() {

View File

@@ -115,7 +115,6 @@ import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkState;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
@@ -386,8 +385,7 @@ public class NetworkPolicyManagerServiceTest {
Log.d(TAG, "set mUidObserver to " + mUidObserver);
return null;
}
}).when(mActivityManager).registerUidObserver(any(), anyInt(),
eq(NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE), any(String.class));
}).when(mActivityManager).registerUidObserver(any(), anyInt(), anyInt(), any(String.class));
mFutureIntent = newRestrictBackgroundChangedFuture();
mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,