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

Commit a0536438 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Add annotation to the performance sensitive methods

So we can evaluate more easily later if something can be optimized.

Also:
- Make ActiveUids a separated lock to reduce locking WM.
- Use more lock-without-boost for the methods that are already
  in another priority booster.

Bug: 122505787
Test: Boot device
Change-Id: I2e942b1f0b888e155f622ddbc850a481c0c88578
parent cb889759
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -936,7 +936,7 @@ class ActivityStarter {
            return false;
        }
        // don't abort if the callingUid is in the foreground or is a persistent system process
        final int callingUidProcState = mService.getUidStateLocked(callingUid);
        final int callingUidProcState = mService.getUidState(callingUid);
        final boolean callingUidHasAnyVisibleWindow =
                mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
        final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
@@ -949,7 +949,7 @@ class ActivityStarter {
        // take realCallingUid into consideration
        final int realCallingUidProcState = (callingUid == realCallingUid)
                ? callingUidProcState
                : mService.getUidStateLocked(realCallingUid);
                : mService.getUidState(realCallingUid);
        final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
                ? callingUidHasAnyVisibleWindow
                : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(realCallingUid);
+51 −30
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import static android.Manifest.permission.REMOVE_TASKS;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.Manifest.permission.STOP_APP_SWITCHES;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
@@ -272,6 +271,10 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.ref.WeakReference;
import java.text.DateFormat;
import java.util.ArrayList;
@@ -363,7 +366,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    private UserManagerService mUserManager;
    private AppOpsService mAppOpsService;
    /** All active uids in the system. */
    private final SparseArray<Integer> mActiveUids = new SparseArray<>();
    private final MirrorActiveUids mActiveUids = new MirrorActiveUids();
    private final SparseArray<String> mPendingTempWhitelist = new SparseArray<>();
    /** All processes currently running that might have a window organized by name. */
    final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
@@ -647,6 +650,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        }
    }

    /** Indicates that the method may be invoked frequently or is sensitive to performance. */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    @interface HotPath {
        int NONE = 0;
        int OOM_ADJUSTMENT = 1;
        int LRU_UPDATE = 2;
        int PROCESS_CHANGE = 3;
        int caller() default NONE;
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public ActivityTaskManagerService(Context context) {
        mContext = context;
@@ -5709,12 +5723,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        return null;
    }

    int getUidStateLocked(int uid) {
        return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
    int getUidState(int uid) {
        return mActiveUids.getUidState(uid);
    }

    boolean isUidForeground(int uid) {
        return (getUidStateLocked(uid) == ActivityManager.PROCESS_STATE_TOP)
        return (getUidState(uid) == ActivityManager.PROCESS_STATE_TOP)
                || mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid);
    }

@@ -6109,23 +6123,26 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            }
        }

        @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public void onProcessAdded(WindowProcessController proc) {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                mProcessNames.put(proc.mName, proc.mUid, proc);
            }
        }

        @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public void onProcessRemoved(String name, int uid) {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                mProcessNames.remove(name, uid);
            }
        }

        @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public void onCleanUpApplicationRecord(WindowProcessController proc) {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                if (proc == mHomeProcess) {
                    mHomeProcess = null;
                }
@@ -6135,23 +6152,26 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            }
        }

        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public int getTopProcessState() {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                return mTopProcessState;
            }
        }

        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public boolean isHeavyWeightProcess(WindowProcessController proc) {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                return proc == mHeavyWeightProcess;
            }
        }

        @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
            }
        }
@@ -6167,9 +6187,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            }
        }

        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public boolean isSleeping() {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                return isSleepingLocked();
            }
        }
@@ -6413,9 +6434,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            }
        }

        @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public boolean isFactoryTestProcess(WindowProcessController wpc) {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                if (mFactoryTest == FACTORY_TEST_OFF) {
                    return false;
                }
@@ -6468,10 +6490,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            }
        }

        @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public void handleAppDied(WindowProcessController wpc, boolean restarting,
                Runnable finishInstrumentationCallback) {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                // Remove this application's activities from active lists.
                boolean hasVisibleActivities = mRootActivityContainer.handleAppDied(wpc);

@@ -6570,16 +6593,18 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            }
        }

        @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public void preBindApplication(WindowProcessController wpc) {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
            }
        }

        @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLock) {
            synchronized (mGlobalLockWithoutBoost) {
                return mRootActivityContainer.attachApplication(wpc);
            }
        }
@@ -6907,6 +6932,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            }
        }

        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public WindowProcessController getTopApp() {
            synchronized (mGlobalLockWithoutBoost) {
@@ -6915,6 +6941,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            }
        }

        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public void rankTaskLayersIfNeeded() {
            synchronized (mGlobalLockWithoutBoost) {
@@ -6959,34 +6986,28 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            }
        }

        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public void onUidActive(int uid, int procState) {
            synchronized (mGlobalLockWithoutBoost) {
                mActiveUids.put(uid, procState);
            }
            mActiveUids.onUidActive(uid, procState);
        }

        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public void onUidInactive(int uid) {
            synchronized (mGlobalLockWithoutBoost) {
                mActiveUids.remove(uid);
            }
            mActiveUids.onUidInactive(uid);
        }

        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public void onActiveUidsCleared() {
            synchronized (mGlobalLockWithoutBoost) {
                mActiveUids.clear();
            }
            mActiveUids.onActiveUidsCleared();
        }

        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public void onUidProcStateChanged(int uid, int procState) {
            synchronized (mGlobalLockWithoutBoost) {
                if (mActiveUids.get(uid) != null) {
                    mActiveUids.put(uid, procState);
                }
            }
            mActiveUids.onUidProcStateChanged(uid, procState);
        }

        @Override
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wm;

import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;

import android.util.SparseIntArray;

/**
 * This is a partial mirror of {@link @com.android.server.am.ActiveUids}. It is already thread
 * safe so the heavy service lock is not needed when updating state from activity manager (oom
 * adjustment) or getting state from window manager (background start check).
 */
class MirrorActiveUids {
    private SparseIntArray mUidStates = new SparseIntArray();

    synchronized void onUidActive(int uid, int procState) {
        mUidStates.put(uid, procState);
    }

    synchronized void onUidInactive(int uid) {
        mUidStates.delete(uid);
    }

    synchronized void onActiveUidsCleared() {
        mUidStates.clear();
    }

    synchronized void onUidProcStateChanged(int uid, int procState) {
        final int index = mUidStates.indexOfKey(uid);
        if (index >= 0) {
            mUidStates.setValueAt(index, procState);
        }
    }

    synchronized int getUidState(int uid) {
        return mUidStates.get(uid, PROCESS_STATE_NONEXISTENT);
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.Watchdog;
import com.android.server.wm.ActivityTaskManagerService.HotPath;

import java.io.IOException;
import java.io.PrintWriter;
@@ -408,12 +409,14 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        return null;
    }

    @HotPath(caller = HotPath.PROCESS_CHANGE)
    public void addPackage(String packageName) {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            mPkgList.add(packageName);
        }
    }

    @HotPath(caller = HotPath.PROCESS_CHANGE)
    public void clearPackageList() {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            mPkgList.clear();
@@ -441,12 +444,14 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        mActivities.clear();
    }

    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
    public boolean hasActivities() {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            return !mActivities.isEmpty();
        }
    }

    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
    public boolean hasVisibleActivities() {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            for (int i = mActivities.size() - 1; i >= 0; --i) {
@@ -459,6 +464,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        return false;
    }

    @HotPath(caller = HotPath.LRU_UPDATE)
    public boolean hasActivitiesOrRecentTasks() {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            return !mActivities.isEmpty() || !mRecentTasks.isEmpty();
@@ -670,6 +676,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        void onOtherActivity();
    }

    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
    public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            final int activitiesSize = mActivities.size();
@@ -903,6 +910,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        mRecentTasks.remove(task);
    }

    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
    public boolean hasRecentTasks() {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            return !mRecentTasks.isEmpty();
@@ -966,18 +974,21 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        return false;
    }

    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
    public void onTopProcChanged() {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            mAtm.mVrController.onTopProcChangedLocked(this);
        }
    }

    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
    public boolean isHomeProcess() {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            return this == mAtm.mHomeProcess;
        }
    }

    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
    public boolean isPreviousProcess() {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            return this == mAtm.mPreviousProcess;
+2 −2
Original line number Diff line number Diff line
@@ -661,8 +661,8 @@ public class ActivityStarterTests extends ActivityTestsBase {
        doReturn(realCallingUidHasVisibleWindow).when(mService.mWindowManager.mRoot)
                .isAnyNonToastWindowVisibleForUid(realCallingUid);
        // process importance
        doReturn(callingUidProcState).when(mService).getUidStateLocked(callingUid);
        doReturn(realCallingUidProcState).when(mService).getUidStateLocked(realCallingUid);
        doReturn(callingUidProcState).when(mService).getUidState(callingUid);
        doReturn(realCallingUidProcState).when(mService).getUidState(realCallingUid);
        // foreground activities
        final IApplicationThread caller = mock(IApplicationThread.class);
        final ApplicationInfo ai = new ApplicationInfo();