Moved more stuff from ActivityManagerService to ActivityTaskManagerService (15/n)
- Moved CompatModePackages to ActivityTaskManagerService since it is mostly used for activity stuff.
- Moved mHeavyWeightProcess to ActivityTaskManagerService since it is set for activities.
- Set AMS.mBooting and AMS.mBooted as volatile to allow setting from both AM and WM side with hold locks.
- Allow updating of cpu stats, usage stats, and foreground time from WM side.
Bug: 80414790
Test: Existing tests pass.
Change-Id: I48ab55bdd5aacc864cb6a82d19d1a24b7605a5b0
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 212844a..fa7f0cb 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -125,7 +125,11 @@
import android.app.IActivityTaskManager;
import android.app.IApplicationThread;
import android.app.IAssistDataReceiver;
+import android.app.INotificationManager;
import android.app.ITaskStackListener;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.app.ProfilerInfo;
import android.app.RemoteAction;
@@ -150,6 +154,7 @@
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
+import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -208,10 +213,13 @@
import com.android.internal.app.ProcessMap;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.AppOpsService;
import com.android.server.AttributeCache;
import com.android.server.LocalServices;
@@ -266,6 +274,7 @@
ActivityManagerInternal mAmInternal;
UriGrantsManagerInternal mUgmInternal;
private PackageManagerInternal mPmInternal;
+ private ActivityTaskManagerInternal mInternal;
/* Global service lock used by the package the owns this service. */
Object mGlobalLock;
ActivityStackSupervisor mStackSupervisor;
@@ -278,6 +287,8 @@
final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
/** This is the process holding what we currently consider to be the "home" activity. */
WindowProcessController mHomeProcess;
+ /** The currently running heavy-weight process, if any. */
+ WindowProcessController mHeavyWeightProcess = null;
/**
* This is the process holding the activity the user last visited that is in a different process
* from the one they are currently in.
@@ -475,6 +486,12 @@
private AppWarnings mAppWarnings;
+ /**
+ * Packages that the user has asked to have run in screen size
+ * compatibility mode instead of filling the screen.
+ */
+ CompatModePackages mCompatModePackages;
+
private FontScaleSettingObserver mFontScaleSettingObserver;
private final class FontScaleSettingObserver extends ContentObserver {
@@ -607,8 +624,9 @@
mGlobalLock = mAm;
mH = new H(mAm.mHandlerThread.getLooper());
mUiHandler = new UiHandler();
- mAppWarnings = new AppWarnings(
- this, mUiContext, mH, mUiHandler, SystemServiceManager.ensureSystemDir());
+ final File systemDir = SystemServiceManager.ensureSystemDir();
+ mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
+ mCompatModePackages = new CompatModePackages(this, systemDir, mH);
mTempConfig.setToDefaults();
mTempConfig.setLocales(LocaleList.getDefault());
@@ -687,7 +705,8 @@
}
private void start() {
- LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
+ mInternal = new LocalService();
+ LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}
public static final class Lifecycle extends SystemService {
@@ -1461,16 +1480,13 @@
@Override
public int getFrontActivityScreenCompatMode() {
enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
- ApplicationInfo ai;
synchronized (mGlobalLock) {
final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
if (r == null) {
return ActivityManager.COMPAT_MODE_UNKNOWN;
}
- ai = r.info.applicationInfo;
+ return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
}
-
- return mAmInternal.getPackageScreenCompatMode(ai);
}
@Override
@@ -1485,9 +1501,8 @@
return;
}
ai = r.info.applicationInfo;
+ mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
}
-
- mAmInternal.setPackageScreenCompatMode(ai, mode);
}
@Override
@@ -4112,7 +4127,7 @@
return mVrController.shouldDisableNonVrUiLocked();
}
- void applyUpdateVrModeLocked(ActivityRecord r) {
+ private void applyUpdateVrModeLocked(ActivityRecord r) {
// VR apps are expected to run in a main display. If an app is turning on VR for
// itself, but lives in a dynamic stack, then make sure that it is moved to the main
// fullscreen stack before enabling VR Mode.
@@ -4143,6 +4158,40 @@
});
}
+ @Override
+ public int getPackageScreenCompatMode(String packageName) {
+ enforceNotIsolatedCaller("getPackageScreenCompatMode");
+ synchronized (mGlobalLock) {
+ return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
+ }
+ }
+
+ @Override
+ public void setPackageScreenCompatMode(String packageName, int mode) {
+ mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
+ "setPackageScreenCompatMode");
+ synchronized (mGlobalLock) {
+ mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
+ }
+ }
+
+ @Override
+ public boolean getPackageAskScreenCompat(String packageName) {
+ enforceNotIsolatedCaller("getPackageAskScreenCompat");
+ synchronized (mGlobalLock) {
+ return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
+ }
+ }
+
+ @Override
+ public void setPackageAskScreenCompat(String packageName, boolean ask) {
+ mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
+ "setPackageAskScreenCompat");
+ synchronized (mGlobalLock) {
+ mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
+ }
+ }
+
ActivityStack getTopDisplayFocusedStack() {
return mStackSupervisor.getTopDisplayFocusedStack();
}
@@ -4812,6 +4861,122 @@
mH.post(mAmInternal::updateOomAdj);
}
+ void updateCpuStats() {
+ mH.post(mAmInternal::updateCpuStats);
+ }
+
+ void updateUsageStats(ActivityRecord component, boolean resumed) {
+ final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
+ mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
+ mH.sendMessage(m);
+ }
+
+ void setBooting(boolean booting) {
+ mAmInternal.setBooting(booting);
+ }
+
+ boolean isBooting() {
+ return mAmInternal.isBooting();
+ }
+
+ void setBooted(boolean booted) {
+ mAmInternal.setBooted(booted);
+ }
+
+ boolean isBooted() {
+ return mAmInternal.isBooted();
+ }
+
+ void postFinishBooting(boolean finishBooting, boolean enableScreen) {
+ mH.post(() -> {
+ if (finishBooting) {
+ mAmInternal.finishBooting();
+ }
+ if (enableScreen) {
+ mInternal.enableScreenAfterBoot(isBooted());
+ }
+ });
+ }
+
+ void setHeavyWeightProcess(ActivityRecord root) {
+ mHeavyWeightProcess = root.app;
+ final Message m = PooledLambda.obtainMessage(
+ ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
+ root.app, root.intent, root.userId);
+ mH.sendMessage(m);
+ }
+
+ void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
+ if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
+ return;
+ }
+
+ mHeavyWeightProcess = null;
+ final Message m = PooledLambda.obtainMessage(
+ ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
+ proc.mUserId);
+ mH.sendMessage(m);
+ }
+
+ private void cancelHeavyWeightProcessNotification(int userId) {
+ final INotificationManager inm = NotificationManager.getService();
+ if (inm == null) {
+ return;
+ }
+ try {
+ inm.cancelNotificationWithTag("android", null,
+ SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Error canceling notification for service", e);
+ } catch (RemoteException e) {
+ }
+
+ }
+
+ private void postHeavyWeightProcessNotification(
+ WindowProcessController proc, Intent intent, int userId) {
+ if (proc == null) {
+ return;
+ }
+
+ final INotificationManager inm = NotificationManager.getService();
+ if (inm == null) {
+ return;
+ }
+
+ try {
+ Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
+ String text = mContext.getString(R.string.heavy_weight_notification,
+ context.getApplicationInfo().loadLabel(context.getPackageManager()));
+ Notification notification =
+ new Notification.Builder(context,
+ SystemNotificationChannels.HEAVY_WEIGHT_APP)
+ .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+ .setWhen(0)
+ .setOngoing(true)
+ .setTicker(text)
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setContentTitle(text)
+ .setContentText(
+ mContext.getText(R.string.heavy_weight_notification_detail))
+ .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
+ intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
+ new UserHandle(userId)))
+ .build();
+ try {
+ inm.enqueueNotificationWithTag("android", "android", null,
+ SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Error showing notification for heavy-weight app", e);
+ } catch (RemoteException e) {
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Unable to create context for heavy notification", e);
+ }
+
+ }
+
// TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
private void startTimeTrackingFocusedActivityLocked() {
final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
@@ -4888,6 +5053,10 @@
mH.post(() -> mAmInternal.scheduleAppGcs());
}
+ CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
+ return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
+ }
+
/**
* Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
* PackageManager could be unavailable at construction time and therefore needs to be accessed
@@ -5274,6 +5443,28 @@
}
@Override
+ public boolean isHeavyWeightProcess(WindowProcessController proc) {
+ synchronized (mGlobalLock) {
+ return proc == mHeavyWeightProcess;
+ }
+ }
+
+ @Override
+ public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
+ synchronized (mGlobalLock) {
+ ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
+ }
+ }
+
+ @Override
+ public void finishHeavyWeightApp() {
+ synchronized (mGlobalLock) {
+ ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
+ mHeavyWeightProcess);
+ }
+ }
+
+ @Override
public boolean isSleeping() {
synchronized (mGlobalLock) {
return isSleepingLocked();
@@ -5382,6 +5573,7 @@
@Override
public void onPackageDataCleared(String name) {
synchronized (mGlobalLock) {
+ mCompatModePackages.handlePackageDataClearedLocked(name);
mAppWarnings.onPackageDataCleared(name);
}
}
@@ -5390,7 +5582,23 @@
public void onPackageUninstalled(String name) {
synchronized (mGlobalLock) {
mAppWarnings.onPackageUninstalled(name);
+ mCompatModePackages.handlePackageUninstalledLocked(name);
}
}
+
+ @Override
+ public void onPackageAdded(String name, boolean replacing) {
+ synchronized (mGlobalLock) {
+ mCompatModePackages.handlePackageAddedLocked(name, replacing);
+ }
+ }
+
+ @Override
+ public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
+ synchronized (mGlobalLock) {
+ return compatibilityInfoForPackageLocked(ai);
+ }
+ }
+
}
}