summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/res/res/values/config.xml8
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java66
3 files changed, 76 insertions, 0 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 929133f792c0..5a1f2d1ae680 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5548,6 +5548,14 @@
<!-- Add packages here -->
</string-array>
+ <!-- Enable pause wallpaper rendering upon state change such as app launch -->
+ <bool name="config_pauseWallpaperRenderWhenStateChangeEnabled">false</bool>
+
+ <!-- The list of packages to pause wallpaper rendering upon state change such as app launch -->
+ <string-array name="pause_wallpaper_render_when_state_change" translatable="false">
+ <!-- Add packages here -->
+ </string-array>
+
<!-- Whether or not to hide the navigation bar when the soft keyboard is visible in order to
create additional screen real estate outside beyond the keyboard. Note that the user needs
to have a confirmed way to dismiss the keyboard when desired. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2b9194f8c54e..8e1c09ede581 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4308,6 +4308,8 @@
<java-symbol type="string" name="config_factoryResetPackage" />
<java-symbol type="array" name="config_highRefreshRateBlacklist" />
<java-symbol type="array" name="config_forceSlowJpegModeList" />
+ <java-symbol type="array" name="pause_wallpaper_render_when_state_change" />
+ <java-symbol type="bool" name="config_pauseWallpaperRenderWhenStateChangeEnabled" />
<java-symbol type="array" name="config_smallAreaDetectionAllowlist" />
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 4200fbf39ade..c7a3c4349f4c 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -51,6 +51,7 @@ import android.app.ILocalWallpaperColorConsumer;
import android.app.IWallpaperManager;
import android.app.IWallpaperManagerCallback;
import android.app.PendingIntent;
+import android.app.UidObserver;
import android.app.UserSwitchObserver;
import android.app.WallpaperColors;
import android.app.WallpaperInfo;
@@ -103,6 +104,7 @@ import android.service.wallpaper.WallpaperService;
import android.system.ErrnoException;
import android.system.Os;
import android.util.EventLog;
+import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -120,6 +122,7 @@ import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.pm.UserManagerInternal;
import com.android.server.utils.TimingsTraceAndSlog;
+import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;
import org.xmlpull.v1.XmlPullParserException;
@@ -1645,6 +1648,40 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
mWallpaperDisplayHelper = new WallpaperDisplayHelper(dm, mWindowManagerInternal);
mWallpaperCropper = new WallpaperCropper(mWallpaperDisplayHelper);
mActivityManager = mContext.getSystemService(ActivityManager.class);
+
+ if (mContext.getResources().getBoolean(
+ R.bool.config_pauseWallpaperRenderWhenStateChangeEnabled)) {
+ // Pause wallpaper rendering engine as soon as a performance impacted app is launched.
+ final String[] pauseRenderList = mContext.getResources().getStringArray(
+ R.array.pause_wallpaper_render_when_state_change);
+ final IntArray pauseRenderUids = new IntArray();
+ for (String pauseRenderApp : pauseRenderList) {
+ try {
+ int uid = mContext.getPackageManager().getApplicationInfo(
+ pauseRenderApp, 0).uid;
+ pauseRenderUids.add(uid);
+ } catch (Exception e) {
+ Slog.e(TAG, e.toString());
+ }
+ }
+ if (pauseRenderUids.size() > 0) {
+ try {
+ ActivityManager.getService().registerUidObserverForUids(new UidObserver() {
+ @Override
+ public void onUidStateChanged(int uid, int procState, long procStateSeq,
+ int capability) {
+ pauseOrResumeRenderingImmediately(
+ procState == ActivityManager.PROCESS_STATE_TOP);
+ }
+ }, ActivityManager.UID_OBSERVER_PROCSTATE,
+ ActivityManager.PROCESS_STATE_TOP, "android",
+ pauseRenderUids.toArray());
+ } catch (RemoteException e) {
+ Slog.e(TAG, e.toString());
+ }
+ }
+ }
+
mMonitor = new MyPackageMonitor();
mColorsChangedListeners = new SparseArray<>();
mWallpaperDataParser = new WallpaperDataParser(mContext, mWallpaperDisplayHelper,
@@ -2625,6 +2662,35 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
+ private void pauseOrResumeRenderingImmediately(boolean pause) {
+ synchronized (mLock) {
+ final WallpaperData[] wallpapers = mIsLockscreenLiveWallpaperEnabled
+ ? getActiveWallpapers() : new WallpaperData[] {
+ mWallpaperMap.get(mCurrentUserId) };
+ for (WallpaperData data : wallpapers) {
+ if (data.connection == null || data.connection.mInfo == null) {
+ continue;
+ }
+ if (pause || LocalServices.getService(ActivityTaskManagerInternal.class)
+ .isUidForeground(data.connection.mInfo.getServiceInfo()
+ .applicationInfo.uid)) {
+ if (data.connection.containsDisplay(
+ mWindowManagerInternal.getTopFocusedDisplayId())) {
+ data.connection.forEachDisplayConnector(displayConnector -> {
+ if (displayConnector.mEngine != null) {
+ try {
+ displayConnector.mEngine.setVisibility(!pause);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to set visibility", e);
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+
/**
* Propagate a wake event to the wallpaper engine(s).
*/