Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 300fb3a0 authored by chengfeitao's avatar chengfeitao
Browse files

Pause wallpaper rendering upon launching GCA

Implementation of go/wp-vis-short

Bug: b/297893016
Test: atest WallpaperManagerTest –iterations 5
Test: pending manual testing from fennychang for 1p live wallpaper
Test: pending testing from devincody to confirm the effectiveness of the
fix on GCA launch perfetto traces

Change-Id: I78d0b7764abe4edf3776a9add3da3572fba4443d
parent 14a320dc
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -5521,6 +5521,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. -->
+2 −0
Original line number Diff line number Diff line
@@ -4298,6 +4298,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" />

+66 −0
Original line number Diff line number Diff line
@@ -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).
     */