mConstants = hasHandlerThread ? new ActivityManagerConstants(this, mHandler) : null;
final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */);
mProcessList.init(this, activeUids);
- mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);
+ mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids, new Object());
mIntentFirewall = hasHandlerThread
? new IntentFirewall(new IntentFirewallInterface(), mHandler) : null;
mConstants = new ActivityManagerConstants(this, mHandler);
final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */);
mProcessList.init(this, activeUids);
- mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);
+ mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids, atm.getGlobalLock());
// Broadcast policy parameters
final BroadcastConstants foreConstants = new BroadcastConstants(
} else {
UidRecord validateUid = mValidateUids.get(item.uid);
if (validateUid == null) {
- validateUid = new UidRecord(item.uid, mAtmInternal);
+ validateUid = new UidRecord(item.uid);
mValidateUids.put(item.uid, validateUid);
}
if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
private final ActivityManagerService mService;
private final ProcessList mProcessList;
- OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids) {
+ /**
+ * Used to lock {@link #updateOomAdjImpl} for state consistency. It also reduces frequency lock
+ * and unlock when getting and setting value to {@link ProcessRecord#mWindowProcessController}.
+ * Note it is declared as Object type so the locked-region-code-injection won't wrap the
+ * unnecessary priority booster.
+ */
+ private final Object mAtmGlobalLock;
+
+ OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids,
+ Object atmGlobalLock) {
mService = service;
+ mAtmGlobalLock = atmGlobalLock;
mProcessList = processList;
mActiveUids = activeUids;
@GuardedBy("mService")
final void updateOomAdjLocked() {
+ synchronized (mAtmGlobalLock) {
+ updateOomAdjImpl();
+ }
+ }
+
+ @GuardedBy({"mService", "mAtmGlobalLock"})
+ private void updateOomAdjImpl() {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "updateOomAdj");
mService.mOomAdjProfiler.oomAdjStarted();
final ProcessRecord TOP_APP = mService.getTopAppLocked();
uidRec.setProcState = uidRec.getCurProcState();
uidRec.setWhitelist = uidRec.curWhitelist;
uidRec.setIdle = uidRec.idle;
+ mService.mAtmInternal.onUidProcStateChanged(uidRec.uid, uidRec.setProcState);
mService.enqueueUidChangeLocked(uidRec, -1, uidChange);
mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
if (uidRec.foregroundServices) {
}
UidRecord uidRec = mActiveUids.get(proc.uid);
if (uidRec == null) {
- uidRec = new UidRecord(proc.uid, mService.mAtmInternal);
+ uidRec = new UidRecord(proc.uid);
// This is the first appearance of the uid, report it now!
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
"Creating new process uid: " + uidRec);
return mWindowProcessController.hasActivities();
}
- void clearActivities() {
- mWindowProcessController.clearActivities();
- }
-
boolean hasActivitiesOrRecentTasks() {
return mWindowProcessController.hasActivitiesOrRecentTasks();
}
return mWindowProcessController.hasRecentTasks();
}
- void clearRecentTasks() {
- mWindowProcessController.clearRecentTasks();
- }
-
/**
* This method returns true if any of the activities within the process record are interesting
* to the user. See HistoryRecord.isInterestingToUserLocked()
import android.util.proto.ProtoUtils;
import com.android.internal.annotations.GuardedBy;
-import com.android.server.wm.ActivityTaskManagerInternal;
/**
* Overall information about a uid that has actively running processes.
boolean idle;
boolean setIdle;
int numProcs;
- final ActivityTaskManagerInternal mAtmInternal;
/**
* Sequence number associated with the {@link #mCurProcState}. This is incremented using
ChangeItem pendingChange;
int lastReportedChange;
- public UidRecord(int _uid, ActivityTaskManagerInternal atmInternal) {
+ public UidRecord(int _uid) {
uid = _uid;
idle = true;
- mAtmInternal = atmInternal;
reset();
}
public void setCurProcState(int curProcState) {
mCurProcState = curProcState;
- if (mAtmInternal != null) {
- mAtmInternal.onUidProcStateChanged(uid, curProcState);
- }
}
public void reset() {
/* Global service lock used by the package the owns this service. */
final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock();
+ /**
+ * It is the same instance as {@link mGlobalLock}, just declared as a type that the
+ * locked-region-code-injection does't recognize it. It is used to skip wrapping priority
+ * booster for places that are already in the scope of another booster (e.g. computing oom-adj).
+ *
+ * @see WindowManagerThreadPriorityBooster
+ */
+ final Object mGlobalLockWithoutBoost = mGlobalLock;
ActivityStackSupervisor mStackSupervisor;
RootActivityContainer mRootActivityContainer;
WindowManagerService mWindowManager;
@Override
public WindowProcessController getTopApp() {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
final ActivityRecord top = mRootActivityContainer.getTopResumedActivity();
return top != null ? top.app : null;
}
@Override
public void rankTaskLayersIfNeeded() {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
if (mRootActivityContainer != null) {
mRootActivityContainer.rankTaskLayersIfNeeded();
}
@Override
public void onUidActive(int uid, int procState) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
mActiveUids.put(uid, procState);
}
}
@Override
public void onUidInactive(int uid) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
mActiveUids.remove(uid);
}
}
@Override
public void onActiveUidsCleared() {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
mActiveUids.clear();
}
}
@Override
public void onUidProcStateChanged(int uid, int procState) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
if (mActiveUids.get(uid) != null) {
mActiveUids.put(uid, procState);
}
@Override
public void onUidAddedToPendingTempWhitelist(int uid, String tag) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
mPendingTempWhitelist.put(uid, tag);
}
}
@Override
public void onUidRemovedFromPendingTempWhitelist(int uid) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
mPendingTempWhitelist.remove(uid);
}
}
}
public void addPackage(String packageName) {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
mPkgList.add(packageName);
}
}
public void clearPackageList() {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
mPkgList.clear();
}
}
}
}
- public void clearActivities() {
- synchronized (mAtm.mGlobalLock) {
- mActivities.clear();
- }
+ void clearActivities() {
+ mActivities.clear();
}
public boolean hasActivities() {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
return !mActivities.isEmpty();
}
}
public boolean hasVisibleActivities() {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
for (int i = mActivities.size() - 1; i >= 0; --i) {
final ActivityRecord r = mActivities.get(i);
if (r.visible) {
}
public boolean hasActivitiesOrRecentTasks() {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
return !mActivities.isEmpty() || !mRecentTasks.isEmpty();
}
}
}
}
- public void finishActivities() {
- synchronized (mAtm.mGlobalLock) {
- ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities);
- for (int i = 0; i < activities.size(); i++) {
- final ActivityRecord r = activities.get(i);
- if (!r.finishing && r.isInStackLocked()) {
- r.getActivityStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
- null, "finish-heavy", true);
- }
+ void finishActivities() {
+ ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities);
+ for (int i = 0; i < activities.size(); i++) {
+ final ActivityRecord r = activities.get(i);
+ if (!r.finishing && r.isInStackLocked()) {
+ r.getActivityStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
+ null, "finish-heavy", true);
}
}
}
}
- public void updateIntentForHeavyWeightActivity(Intent intent) {
- synchronized (mAtm.mGlobalLock) {
- if (mActivities.isEmpty()) {
- return;
- }
- ActivityRecord hist = mActivities.get(0);
- intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
- intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTaskRecord().taskId);
+ void updateIntentForHeavyWeightActivity(Intent intent) {
+ if (mActivities.isEmpty()) {
+ return;
}
+ ActivityRecord hist = mActivities.get(0);
+ intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
+ intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTaskRecord().taskId);
}
boolean shouldKillProcessForRemovedTask(TaskRecord tr) {
}
public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
final int activitiesSize = mActivities.size();
for (int j = 0; j < activitiesSize; j++) {
final ActivityRecord r = mActivities.get(j);
}
public boolean hasRecentTasks() {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
return !mRecentTasks.isEmpty();
}
}
- public void clearRecentTasks() {
- synchronized (mAtm.mGlobalLock) {
- for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
- mRecentTasks.get(i).clearRootProcess();
- }
- mRecentTasks.clear();
+ void clearRecentTasks() {
+ for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
+ mRecentTasks.get(i).clearRootProcess();
}
+ mRecentTasks.clear();
}
public void appEarlyNotResponding(String annotation, Runnable killAppCallback) {
}
public void onTopProcChanged() {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
mAtm.mVrController.onTopProcChangedLocked(this);
}
}
public boolean isHomeProcess() {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
return this == mAtm.mHomeProcess;
}
}
public boolean isPreviousProcess() {
- synchronized (mAtm.mGlobalLock) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
return this == mAtm.mPreviousProcess;
}
}
private UidRecord addActiveUidRecord(int uid, long curProcStateSeq,
long lastNetworkUpdatedProcStateSeq) {
- final UidRecord record = new UidRecord(uid, null /* atmInternal */);
+ final UidRecord record = new UidRecord(uid);
record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
record.curProcStateSeq = curProcStateSeq;
record.waitingForNetwork = true;
}
private UidRecord addUidRecord(int uid) {
- final UidRecord uidRec = new UidRecord(uid, null /* atmInternal */);
+ final UidRecord uidRec = new UidRecord(uid);
uidRec.waitingForNetwork = true;
uidRec.hasInternetPermission = true;
mAms.mProcessList.mActiveUids.put(uid, uidRec);
@Test
public void testBlockStateForUid() {
- final UidRecord uidRec = new UidRecord(TEST_UID, null /* atmInternal */);
+ final UidRecord uidRec = new UidRecord(TEST_UID);
int expectedBlockState;
final String errorTemplate = "Block state should be %s, prevState: %s, curState: %s";
@Test
public void testEnqueueUidChangeLocked_procStateSeqUpdated() {
- final UidRecord uidRecord = new UidRecord(TEST_UID, null /* atmInternal */);
+ final UidRecord uidRecord = new UidRecord(TEST_UID);
uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
// Verify with no pending changes for TEST_UID.
@MediumTest
@Test
public void testEnqueueUidChangeLocked_dispatchUidsChanged() {
- final UidRecord uidRecord = new UidRecord(TEST_UID, null /* atmInternal */);
+ final UidRecord uidRecord = new UidRecord(TEST_UID);
final int expectedProcState = PROCESS_STATE_SERVICE;
uidRecord.setProcState = expectedProcState;
uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
private void verifyWaitingForNetworkStateUpdate(long curProcStateSeq,
long lastDispatchedProcStateSeq, long lastNetworkUpdatedProcStateSeq,
final long procStateSeqToWait, boolean expectWait) throws Exception {
- final UidRecord record = new UidRecord(Process.myUid(), null /* atmInternal */);
+ final UidRecord record = new UidRecord(Process.myUid());
record.curProcStateSeq = curProcStateSeq;
record.lastDispatchedProcStateSeq = lastDispatchedProcStateSeq;
record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;