Loading services/core/java/com/android/server/am/ActivityManagerService.java +86 −43 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.Manifest.permission.REMOVE_TASKS; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL; import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY; import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; Loading Loading @@ -15711,7 +15712,7 @@ public class ActivityManagerService extends IActivityManager.Stub } private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, long now) { boolean doingAll, long now, boolean cycleReEval) { if (mAdjSeq == app.adjSeq) { if (app.adjSeq == app.completedAdjSeq) { // This adjustment has already been computed successfully. Loading Loading @@ -15787,10 +15788,11 @@ public class ActivityManagerService extends IActivityManager.Stub app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED); } } app.setCurRawProcState(app.getCurProcState()); app.curAdj = app.maxAdj; app.completedAdjSeq = app.adjSeq; // if curAdj is less than prevAppAdj, then this process was promoted return app.curAdj < prevAppAdj; return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState; } app.systemNoUi = false; Loading Loading @@ -16032,8 +16034,13 @@ public class ActivityManagerService extends IActivityManager.Stub // By default, we use the computed adjustment. It may be changed if // there are applications dependent on our services or providers, but // this gives us a baseline and makes sure we don't get into an // infinite recursion. app.setCurRawAdj(adj); // infinite recursion. If we're re-evaluating due to cycles, use the previously computed // values. app.setCurRawAdj(!cycleReEval ? adj : Math.min(adj, app.getCurRawAdj())); app.setCurRawProcState(!cycleReEval ? procState : Math.min(procState, app.getCurRawProcState())); app.hasStartedServices = false; app.adjSeq = mAdjSeq; Loading Loading @@ -16135,21 +16142,15 @@ public class ActivityManagerService extends IActivityManager.Stub boolean trackedProcState = false; if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { ProcessRecord client = cr.binding.client; computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); if (client.containsCycle) { // We've detected a cycle. We should retry computeOomAdjLocked later in // case a later-checked connection from a client would raise its // priority legitimately. app.containsCycle = true; // If the client has not been completely evaluated, skip using its // priority. Else use the conservative value for now and look for a // better state in the next iteration. if (client.completedAdjSeq < mAdjSeq) { computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now, cycleReEval); if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) { continue; } } int clientAdj = client.getCurRawAdj(); int clientProcState = client.getCurProcState(); int clientProcState = client.getCurRawProcState(); if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. The specific cached state Loading Loading @@ -16234,6 +16235,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (adj > newAdj) { adj = newAdj; app.setCurRawAdj(adj); adjType = "service"; } } Loading Loading @@ -16305,6 +16307,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (procState > clientProcState) { procState = clientProcState; app.setCurRawProcState(procState); if (adjType == null) { adjType = "service"; } Loading Loading @@ -16336,6 +16339,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && a.isActivityVisible()) { adj = ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { if ((cr.flags&Context.BIND_IMPORTANT) != 0) { schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND; Loading Loading @@ -16377,21 +16381,15 @@ public class ActivityManagerService extends IActivityManager.Stub // Being our own client is not interesting. continue; } computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); if (client.containsCycle) { // We've detected a cycle. We should retry computeOomAdjLocked later in // case a later-checked connection from a client would raise its // priority legitimately. app.containsCycle = true; // If the client has not been completely evaluated, skip using its // priority. Else use the conservative value for now and look for a // better state in the next iteration. if (client.completedAdjSeq < mAdjSeq) { computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now, cycleReEval); if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) { continue; } } int clientAdj = client.getCurRawAdj(); int clientProcState = client.getCurProcState(); int clientProcState = client.getCurRawProcState(); if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. Loading @@ -16405,6 +16403,7 @@ public class ActivityManagerService extends IActivityManager.Stub } else { adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); adjType = "provider"; } app.cached &= client.cached; Loading Loading @@ -16440,6 +16439,7 @@ public class ActivityManagerService extends IActivityManager.Stub conn.trackProcState(clientProcState, mAdjSeq, now); if (procState > clientProcState) { procState = clientProcState; app.setCurRawProcState(procState); } if (client.getCurrentSchedulingGroup() > schedGroup) { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; Loading @@ -16465,6 +16465,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (cpr.hasExternalProcessHandles()) { if (adj > ProcessList.FOREGROUND_APP_ADJ) { adj = ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); schedGroup = ProcessList.SCHED_GROUP_DEFAULT; app.cached = false; app.adjType = "ext-provider"; Loading @@ -16476,6 +16477,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; app.setCurRawProcState(procState); if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to external provider: " + app); Loading Loading @@ -16620,6 +16622,7 @@ public class ActivityManagerService extends IActivityManager.Stub app.curAdj = app.modifyRawOomAdj(adj); app.setCurrentSchedulingGroup(schedGroup); app.setCurProcState(procState); app.setCurRawProcState(procState); app.setHasForegroundActivities(foregroundActivities); app.completedAdjSeq = mAdjSeq; Loading @@ -16627,6 +16630,44 @@ public class ActivityManagerService extends IActivityManager.Stub return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState; } /** * Checks if for the given app and client, there's a cycle that should skip over the client * for now or use partial values to evaluate the effect of the client binding. * @param app * @param client * @param procState procstate evaluated so far for this app * @param adj oom_adj evaluated so far for this app * @param cycleReEval whether we're currently re-evaluating due to a cycle, and not the first * evaluation. * @return whether to skip using the client connection at this time */ private boolean shouldSkipDueToCycle(ProcessRecord app, ProcessRecord client, int procState, int adj, boolean cycleReEval) { if (client.containsCycle) { // We've detected a cycle. We should retry computeOomAdjLocked later in // case a later-checked connection from a client would raise its // priority legitimately. app.containsCycle = true; // If the client has not been completely evaluated, check if it's worth // using the partial values. if (client.completedAdjSeq < mAdjSeq) { if (cycleReEval) { // If the partial values are no better, skip until the next // attempt if (client.getCurRawProcState() >= procState && client.getCurRawAdj() >= adj) { return true; } // Else use the client's partial procstate and adj to adjust the // effect of the binding } else { return true; } } } return false; } private static final class RecordPssRunnable implements Runnable { private final ActivityManagerService mService; private final ProcessRecord mProc; Loading Loading @@ -17493,7 +17534,7 @@ public class ActivityManagerService extends IActivityManager.Stub return false; } computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now, false); return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime()); } Loading Loading @@ -17868,12 +17909,14 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i=N-1; i>=0; i--) { ProcessRecord app = mProcessList.mLruProcesses.get(i); app.containsCycle = false; app.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY); app.setCurRawAdj(ProcessList.UNKNOWN_ADJ); } for (int i=N-1; i>=0; i--) { ProcessRecord app = mProcessList.mLruProcesses.get(i); if (!app.killedByAm && app.thread != null) { app.procStateChanged = false; computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now, false); // if any app encountered a cycle, we need to perform an additional loop later retryCycles |= app.containsCycle; Loading Loading @@ -17976,8 +18019,8 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i=0; i<N; i++) { ProcessRecord app = mProcessList.mLruProcesses.get(i); if (!app.killedByAm && app.thread != null && app.containsCycle == true) { if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) { if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now, true)) { retryCycles = true; } } services/core/java/com/android/server/am/ProcessRecord.java +10 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,7 @@ final class ProcessRecord implements WindowProcessListener { int trimMemoryLevel; // Last selected memory trimming level private int mCurProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state private int mRepProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state private int mCurRawProcState = PROCESS_STATE_NONEXISTENT; // Temp state during computation int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for int pssStatType; // The type of stat collection that we are currently requesting Loading Loading @@ -902,6 +903,7 @@ final class ProcessRecord implements WindowProcessListener { if (mRepProcState > newState) { mRepProcState = newState; setCurProcState(newState); setCurRawProcState(newState); for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) { StatsLog.write(StatsLog.PROCESS_STATE_CHANGED, uid, processName, pkgList.keyAt(ipkg), Loading Loading @@ -984,6 +986,14 @@ final class ProcessRecord implements WindowProcessListener { return mCurProcState; } void setCurRawProcState(int curRawProcState) { mCurRawProcState = curRawProcState; } int getCurRawProcState() { return mCurRawProcState; } void setReportedProcState(int repProcState) { mRepProcState = repProcState; for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) { Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +86 −43 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.Manifest.permission.REMOVE_TASKS; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL; import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY; import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; Loading Loading @@ -15711,7 +15712,7 @@ public class ActivityManagerService extends IActivityManager.Stub } private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, long now) { boolean doingAll, long now, boolean cycleReEval) { if (mAdjSeq == app.adjSeq) { if (app.adjSeq == app.completedAdjSeq) { // This adjustment has already been computed successfully. Loading Loading @@ -15787,10 +15788,11 @@ public class ActivityManagerService extends IActivityManager.Stub app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED); } } app.setCurRawProcState(app.getCurProcState()); app.curAdj = app.maxAdj; app.completedAdjSeq = app.adjSeq; // if curAdj is less than prevAppAdj, then this process was promoted return app.curAdj < prevAppAdj; return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState; } app.systemNoUi = false; Loading Loading @@ -16032,8 +16034,13 @@ public class ActivityManagerService extends IActivityManager.Stub // By default, we use the computed adjustment. It may be changed if // there are applications dependent on our services or providers, but // this gives us a baseline and makes sure we don't get into an // infinite recursion. app.setCurRawAdj(adj); // infinite recursion. If we're re-evaluating due to cycles, use the previously computed // values. app.setCurRawAdj(!cycleReEval ? adj : Math.min(adj, app.getCurRawAdj())); app.setCurRawProcState(!cycleReEval ? procState : Math.min(procState, app.getCurRawProcState())); app.hasStartedServices = false; app.adjSeq = mAdjSeq; Loading Loading @@ -16135,21 +16142,15 @@ public class ActivityManagerService extends IActivityManager.Stub boolean trackedProcState = false; if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { ProcessRecord client = cr.binding.client; computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); if (client.containsCycle) { // We've detected a cycle. We should retry computeOomAdjLocked later in // case a later-checked connection from a client would raise its // priority legitimately. app.containsCycle = true; // If the client has not been completely evaluated, skip using its // priority. Else use the conservative value for now and look for a // better state in the next iteration. if (client.completedAdjSeq < mAdjSeq) { computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now, cycleReEval); if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) { continue; } } int clientAdj = client.getCurRawAdj(); int clientProcState = client.getCurProcState(); int clientProcState = client.getCurRawProcState(); if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. The specific cached state Loading Loading @@ -16234,6 +16235,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (adj > newAdj) { adj = newAdj; app.setCurRawAdj(adj); adjType = "service"; } } Loading Loading @@ -16305,6 +16307,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (procState > clientProcState) { procState = clientProcState; app.setCurRawProcState(procState); if (adjType == null) { adjType = "service"; } Loading Loading @@ -16336,6 +16339,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && a.isActivityVisible()) { adj = ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { if ((cr.flags&Context.BIND_IMPORTANT) != 0) { schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND; Loading Loading @@ -16377,21 +16381,15 @@ public class ActivityManagerService extends IActivityManager.Stub // Being our own client is not interesting. continue; } computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); if (client.containsCycle) { // We've detected a cycle. We should retry computeOomAdjLocked later in // case a later-checked connection from a client would raise its // priority legitimately. app.containsCycle = true; // If the client has not been completely evaluated, skip using its // priority. Else use the conservative value for now and look for a // better state in the next iteration. if (client.completedAdjSeq < mAdjSeq) { computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now, cycleReEval); if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) { continue; } } int clientAdj = client.getCurRawAdj(); int clientProcState = client.getCurProcState(); int clientProcState = client.getCurRawProcState(); if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. Loading @@ -16405,6 +16403,7 @@ public class ActivityManagerService extends IActivityManager.Stub } else { adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); adjType = "provider"; } app.cached &= client.cached; Loading Loading @@ -16440,6 +16439,7 @@ public class ActivityManagerService extends IActivityManager.Stub conn.trackProcState(clientProcState, mAdjSeq, now); if (procState > clientProcState) { procState = clientProcState; app.setCurRawProcState(procState); } if (client.getCurrentSchedulingGroup() > schedGroup) { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; Loading @@ -16465,6 +16465,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (cpr.hasExternalProcessHandles()) { if (adj > ProcessList.FOREGROUND_APP_ADJ) { adj = ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); schedGroup = ProcessList.SCHED_GROUP_DEFAULT; app.cached = false; app.adjType = "ext-provider"; Loading @@ -16476,6 +16477,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; app.setCurRawProcState(procState); if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to external provider: " + app); Loading Loading @@ -16620,6 +16622,7 @@ public class ActivityManagerService extends IActivityManager.Stub app.curAdj = app.modifyRawOomAdj(adj); app.setCurrentSchedulingGroup(schedGroup); app.setCurProcState(procState); app.setCurRawProcState(procState); app.setHasForegroundActivities(foregroundActivities); app.completedAdjSeq = mAdjSeq; Loading @@ -16627,6 +16630,44 @@ public class ActivityManagerService extends IActivityManager.Stub return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState; } /** * Checks if for the given app and client, there's a cycle that should skip over the client * for now or use partial values to evaluate the effect of the client binding. * @param app * @param client * @param procState procstate evaluated so far for this app * @param adj oom_adj evaluated so far for this app * @param cycleReEval whether we're currently re-evaluating due to a cycle, and not the first * evaluation. * @return whether to skip using the client connection at this time */ private boolean shouldSkipDueToCycle(ProcessRecord app, ProcessRecord client, int procState, int adj, boolean cycleReEval) { if (client.containsCycle) { // We've detected a cycle. We should retry computeOomAdjLocked later in // case a later-checked connection from a client would raise its // priority legitimately. app.containsCycle = true; // If the client has not been completely evaluated, check if it's worth // using the partial values. if (client.completedAdjSeq < mAdjSeq) { if (cycleReEval) { // If the partial values are no better, skip until the next // attempt if (client.getCurRawProcState() >= procState && client.getCurRawAdj() >= adj) { return true; } // Else use the client's partial procstate and adj to adjust the // effect of the binding } else { return true; } } } return false; } private static final class RecordPssRunnable implements Runnable { private final ActivityManagerService mService; private final ProcessRecord mProc; Loading Loading @@ -17493,7 +17534,7 @@ public class ActivityManagerService extends IActivityManager.Stub return false; } computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now, false); return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime()); } Loading Loading @@ -17868,12 +17909,14 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i=N-1; i>=0; i--) { ProcessRecord app = mProcessList.mLruProcesses.get(i); app.containsCycle = false; app.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY); app.setCurRawAdj(ProcessList.UNKNOWN_ADJ); } for (int i=N-1; i>=0; i--) { ProcessRecord app = mProcessList.mLruProcesses.get(i); if (!app.killedByAm && app.thread != null) { app.procStateChanged = false; computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now, false); // if any app encountered a cycle, we need to perform an additional loop later retryCycles |= app.containsCycle; Loading Loading @@ -17976,8 +18019,8 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i=0; i<N; i++) { ProcessRecord app = mProcessList.mLruProcesses.get(i); if (!app.killedByAm && app.thread != null && app.containsCycle == true) { if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) { if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now, true)) { retryCycles = true; } }
services/core/java/com/android/server/am/ProcessRecord.java +10 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,7 @@ final class ProcessRecord implements WindowProcessListener { int trimMemoryLevel; // Last selected memory trimming level private int mCurProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state private int mRepProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state private int mCurRawProcState = PROCESS_STATE_NONEXISTENT; // Temp state during computation int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for int pssStatType; // The type of stat collection that we are currently requesting Loading Loading @@ -902,6 +903,7 @@ final class ProcessRecord implements WindowProcessListener { if (mRepProcState > newState) { mRepProcState = newState; setCurProcState(newState); setCurRawProcState(newState); for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) { StatsLog.write(StatsLog.PROCESS_STATE_CHANGED, uid, processName, pkgList.keyAt(ipkg), Loading Loading @@ -984,6 +986,14 @@ final class ProcessRecord implements WindowProcessListener { return mCurProcState; } void setCurRawProcState(int curRawProcState) { mCurRawProcState = curRawProcState; } int getCurRawProcState() { return mCurRawProcState; } void setReportedProcState(int repProcState) { mRepProcState = repProcState; for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) { Loading