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

Commit 003ab933 authored by Patrick Williams's avatar Patrick Williams Committed by Android (Google) Code Review
Browse files

Merge "Send SessionTag.SYSUI for sysui and launcher" into main

parents bd9a6b7e 12da4133
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -150,23 +150,24 @@ java_library_static {
    ],

    libs: [
        "services.net",
        "android.frameworks.location.altitude-V2-java",
        "android.hardware.common-V2-java",
        "android.hardware.light-V2.0-java",
        "android.hardware.gnss-V2-java",
        "android.hardware.light-V2.0-java",
        "android.hardware.vibrator-V3-java",
        "androidx.annotation_annotation",
        "app-compat-annotations",
        "device_policy_aconfig_flags_lib",
        "error_prone_annotations",
        "framework-tethering.stubs.module_lib",
        "keepanno-annotations",
        "monet",
        "power_hint_flags_lib",
        "service-art.stubs.system_server",
        "service-permission.stubs.system_server",
        "service-rkp.stubs.system_server",
        "service-sdksandbox.stubs.system_server",
        "device_policy_aconfig_flags_lib",
        "services.net",
    ],
    plugins: ["ImmutabilityAnnotationProcessor"],

+62 −15
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import static com.android.internal.util.FrameworkStatsLog.GPU_HEADROOM_REPORTED_
import static com.android.internal.util.FrameworkStatsLog.GPU_HEADROOM_REPORTED__TYPE__AVERAGE;
import static com.android.internal.util.FrameworkStatsLog.GPU_HEADROOM_REPORTED__TYPE__UNKNOWN_CALCULATION_TYPE;
import static com.android.server.power.hint.Flags.resetOnForkEnabled;
import static com.android.server.power.hint.Flags.useSysuiSessionTag;

import android.Manifest;
import android.adpf.ISessionManager;
@@ -40,11 +41,14 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.IActivityManager;
import android.app.StatsManager;
import android.app.UidObserver;
import android.app.role.RoleManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.hardware.power.ChannelConfig;
import android.hardware.power.CpuHeadroomParams;
import android.hardware.power.CpuHeadroomResult;
@@ -198,6 +202,7 @@ public final class HintManagerService extends SystemService {
    private final NativeWrapper mNativeWrapper;
    private final CleanUpHandler mCleanUpHandler;

    private final IActivityManager mActivityManager;
    private final ActivityManagerInternal mAmInternal;

    private final Context mContext;
@@ -245,6 +250,8 @@ public final class HintManagerService extends SystemService {

    private ISessionManager mSessionManager;

    private int mSysuiUid = Process.INVALID_UID;

    // this cache tracks the expiration time of the items and performs cleanup on lookup
    private static class HeadroomCache<K, V> {
        final List<HeadroomCacheItem> mItemList;
@@ -325,6 +332,7 @@ public final class HintManagerService extends SystemService {
        mNativeWrapper.halInit();
        mHintSessionPreferredRate = mNativeWrapper.halGetHintSessionPreferredRate();
        mUidObserver = new MyUidObserver();
        mActivityManager = Objects.requireNonNull(injector.getIActivityManager());
        mAmInternal = Objects.requireNonNull(
                LocalServices.getService(ActivityManagerInternal.class));
        mPowerHal = injector.createIPower();
@@ -463,6 +471,9 @@ public final class HintManagerService extends SystemService {
            return IPower.Stub.asInterface(
                ServiceManager.waitForDeclaredService(IPower.DESCRIPTOR + "/default"));
        }
        IActivityManager getIActivityManager() {
            return ActivityManager.getService();
        }
    }

    private static class ThreadUsageTracker {
@@ -655,13 +666,16 @@ public final class HintManagerService extends SystemService {
    private void systemReady() {
        Slogf.v(TAG, "Initializing HintManager service...");
        try {
            ActivityManager.getService().registerUidObserver(mUidObserver,
            mActivityManager.registerUidObserver(mUidObserver,
                    ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
                    ActivityManager.PROCESS_STATE_UNKNOWN, null);
        } catch (RemoteException e) {
            // ignored; both services live in system_server
        }

        PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
        mSysuiUid = pm.getPackageUid(pm.getSystemUiServiceComponent().getPackageName(),
            PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
    }

    private void registerStatsCallbacks() {
@@ -1448,20 +1462,8 @@ public final class HintManagerService extends SystemService {
                    }
                }

                if (tag == SessionTag.APP) {
                    // If the category of the app is a game,
                    // we change the session tag to SessionTag.GAME
                    // as it was not previously classified
                    switch (getUidApplicationCategory(callingUid)) {
                        case ApplicationInfo.CATEGORY_GAME -> tag = SessionTag.GAME;
                        case ApplicationInfo.CATEGORY_UNDEFINED ->
                            // We use CATEGORY_UNDEFINED to filter the case when
                            // PackageManager.NameNotFoundException is caught,
                            // which should not happen.
                            tag = SessionTag.APP;
                        default -> tag = SessionTag.APP;
                    }
                }
                tag = updateSessionTag(tag, callingUid);

                config.id = -1;
                Long halSessionPtr = null;
                if (mConfigCreationSupport.get()) {
@@ -2121,6 +2123,51 @@ public final class HintManagerService extends SystemService {
                    powerEfficiency, graphicsPipeline);
        }

        private @SessionTag int updateSessionTag(@SessionTag int incomingTag, int callingUid) {
            if (useSysuiSessionTag() && (isUidSysui(callingUid) || isUidLauncher(callingUid))) {
                return SessionTag.SYSUI;
            }

            if (incomingTag != SessionTag.APP) {
                return incomingTag;
            }

            return switch (getUidApplicationCategory(callingUid)) {
                case ApplicationInfo.CATEGORY_GAME -> SessionTag.GAME;
                case ApplicationInfo.CATEGORY_UNDEFINED ->
                    // We use CATEGORY_UNDEFINED to filter the case when
                    // PackageManager.NameNotFoundException is caught,
                    // which should not happen.
                    SessionTag.APP;
                default -> SessionTag.APP;
            };
        }

        private boolean isUidSysui(int uid) {
            return mSysuiUid != Process.INVALID_UID && mSysuiUid == uid;
        }

        private boolean isUidLauncher(int uid) {
            RoleManager roleManager = Objects.requireNonNull(
                    mContext.getSystemService(RoleManager.class));

            List<String> packages = roleManager.getRoleHolders(RoleManager.ROLE_HOME);
            if (packages.size() != 1) {
                Slog.w(TAG, "Unexpected number of role holders for ROLE_HOME.");
                return false;
            }

            int launcherUid;
            try {
                launcherUid = mPackageManager.getPackageUid(packages.getFirst(),
                        PackageManager.MATCH_DEFAULT_ONLY);
            } catch (PackageManager.NameNotFoundException exception) {
                return false;
            }

            return uid == launcherUid;
        }

        private int getUidApplicationCategory(int uid) {
            try {
                final String packageName = mPackageManager.getNameForUid(uid);
+5 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ android_test {
        "androidx.test.rules",
        "flag-junit",
        "junit",
        "mockito-target-minus-junit4",
        "mockito-target-extended-minus-junit4",
        "platform-test-annotations",
        "services.core",
        "truth",
@@ -21,6 +21,10 @@ android_test {
    libs: [
        "android.test.base.stubs.system",
    ],
    jni_libs: [
        "libdexmakerjvmtiagent",
        "libstaticjvmtiagent",
    ],
    test_suites: [
        "automotive-tests",
        "device-tests",
+2 −0
Original line number Diff line number Diff line
@@ -20,4 +20,6 @@
    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
         android:targetPackage="com.android.server.power.hinttests"
         android:label="ADPF Performance Hint Service Test"/>

    <application android:debuggable="true" />
</manifest>
+108 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.power.hint;


import static com.android.server.power.hint.Flags.FLAG_USE_SYSUI_SESSION_TAG;
import static com.android.server.power.hint.HintManagerService.CLEAN_UP_UID_DELAY_MILLIS;

import static com.google.common.truth.Truth.assertThat;
@@ -45,9 +46,13 @@ import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.IActivityManager;
import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.hardware.common.fmq.MQDescriptor;
import android.hardware.power.ChannelConfig;
import android.hardware.power.ChannelMessage;
@@ -70,6 +75,7 @@ import android.os.PerformanceHintManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.SessionCreationConfig;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.flag.junit.SetFlagsRule;
@@ -79,6 +85,7 @@ import androidx.test.InstrumentationRegistry;

import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.power.hint.HintManagerService.AppHintSession;
import com.android.server.power.hint.HintManagerService.Injector;
import com.android.server.power.hint.HintManagerService.NativeWrapper;
@@ -160,10 +167,16 @@ public class HintManagerServiceTest {
    @Mock
    private IPower mIPowerMock;
    @Mock
    private IActivityManager mIActivityManagerMock;
    @Mock
    private ActivityManagerInternal mAmInternalMock;
    @Mock
    private PackageManager mMockPackageManager;
    @Mock
    private RoleManager mMockRoleManager;
    @Mock
    private PackageManagerInternal mPackageManagerInternalMock;
    @Mock
    private IHintManager.IHintManagerClient mClientCallback;
    @Rule
    public final CheckFlagsRule mCheckFlagsRule =
@@ -214,6 +227,7 @@ public class HintManagerServiceTest {
        applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
        mSupportInfo = makeDefaultSupportInfo();
        when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
        when(mContext.getSystemService(RoleManager.class)).thenReturn(mMockRoleManager);
        when(mMockPackageManager.getNameForUid(anyInt())).thenReturn(TEST_APP_NAME);
        when(mMockPackageManager.getApplicationInfo(eq(TEST_APP_NAME), anyInt()))
                .thenReturn(applicationInfo);
@@ -244,6 +258,8 @@ public class HintManagerServiceTest {
        when(mIPowerMock.getSupportInfo()).thenReturn(mSupportInfo);
        LocalServices.removeServiceForTest(ActivityManagerInternal.class);
        LocalServices.addService(ActivityManagerInternal.class, mAmInternalMock);
        LocalServices.removeServiceForTest(PackageManagerInternal.class);
        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
    }

    @After
@@ -334,7 +350,13 @@ public class HintManagerServiceTest {
            IPower createIPower() {
                return mIPowerMock;
            }
            IActivityManager getIActivityManager() {
                return mIActivityManagerMock;
            }
        });
        when(mPackageManagerInternalMock.getSystemUiServiceComponent())
                .thenReturn(new ComponentName("", ""));
        mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
        return mService;
    }

@@ -379,6 +401,92 @@ public class HintManagerServiceTest {
                        SessionTag.OTHER, creationConfig, config));
    }

    @Test
    public void testCreateHintSessionNoChangeToSessionTag() throws Exception {
        HintManagerService service = createService();
        IBinder token = new Binder();
        SessionCreationConfig creationConfig =
                makeSessionCreationConfig(new int[]{TID}, DEFAULT_TARGET_DURATION);
        SessionConfig config = new SessionConfig();
        int tag = SessionTag.OTHER;

        service.getBinderServiceInstance()
                .createHintSessionWithConfig(token, tag, creationConfig, config);

        verify(mNativeWrapperMock).halCreateHintSessionWithConfig(
                anyInt(), anyInt(), any(), anyLong(), eq(tag), any());
    }

    @Test
    public void testCreateHintSessionUpdatesAppTagToGame() throws Exception {
        ApplicationInfo applicationInfo = new ApplicationInfo();
        applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
        when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenReturn(applicationInfo);
        HintManagerService service = createService();
        IBinder token = new Binder();
        SessionCreationConfig creationConfig =
                makeSessionCreationConfig(new int[]{TID}, DEFAULT_TARGET_DURATION);
        SessionConfig config = new SessionConfig();

        service.getBinderServiceInstance()
                .createHintSessionWithConfig(token, SessionTag.APP, creationConfig, config);

        verify(mNativeWrapperMock).halCreateHintSessionWithConfig(
                anyInt(), anyInt(), any(), anyLong(), eq(SessionTag.GAME), any());
    }

    @Test
    public void testCreateHintSessionAppTagUnchanged() throws Exception {
        ApplicationInfo applicationInfo = new ApplicationInfo();
        when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenReturn(applicationInfo);
        HintManagerService service = createService();
        IBinder token = new Binder();
        SessionCreationConfig creationConfig =
                makeSessionCreationConfig(new int[]{TID}, DEFAULT_TARGET_DURATION);
        SessionConfig config = new SessionConfig();

        service.getBinderServiceInstance()
                .createHintSessionWithConfig(token, SessionTag.APP, creationConfig, config);

        verify(mNativeWrapperMock).halCreateHintSessionWithConfig(
                anyInt(), anyInt(), any(), anyLong(), eq(SessionTag.APP), any());
    }

    @RequiresFlagsEnabled(FLAG_USE_SYSUI_SESSION_TAG)
    @Test
    public void testCreateHintSessionSetsSysuiTagWhenCallerIsSysui() throws Exception {
        when(mPackageManagerInternalMock.getPackageUid(any(), anyLong(), anyInt())).thenReturn(UID);
        HintManagerService service = createService();
        IBinder token = new Binder();
        SessionCreationConfig creationConfig =
                makeSessionCreationConfig(new int[]{TID}, DEFAULT_TARGET_DURATION);
        SessionConfig config = new SessionConfig();

        service.getBinderServiceInstance()
                .createHintSessionWithConfig(token, SessionTag.APP, creationConfig, config);

        verify(mNativeWrapperMock).halCreateHintSessionWithConfig(
                anyInt(), anyInt(), any(), anyLong(), eq(SessionTag.SYSUI), any());
    }

    @RequiresFlagsEnabled(FLAG_USE_SYSUI_SESSION_TAG)
    @Test
    public void testCreateHintSessionSetsSysuiTagWhenCallerIsLauncher() throws Exception {
        when(mMockRoleManager.getRoleHolders(any())).thenReturn(List.of("<mock-package-name>"));
        when(mMockPackageManager.getPackageUid(any(), anyInt())).thenReturn(UID);
        HintManagerService service = createService();
        IBinder token = new Binder();
        SessionCreationConfig creationConfig =
                makeSessionCreationConfig(new int[]{TID}, DEFAULT_TARGET_DURATION);
        SessionConfig config = new SessionConfig();

        service.getBinderServiceInstance()
                .createHintSessionWithConfig(token, SessionTag.APP, creationConfig, config);

        verify(mNativeWrapperMock).halCreateHintSessionWithConfig(
                anyInt(), anyInt(), any(), anyLong(), eq(SessionTag.SYSUI), any());
    }

    @Test
    public void testCreateHintSessionFallback() throws Exception {
        HintManagerService service = createService();