Loading services/core/java/com/android/server/am/ProcessList.java +63 −31 Original line number Diff line number Diff line Loading @@ -3629,42 +3629,68 @@ public final class ProcessList { } @GuardedBy({"mService", "mProcLock"}) private int updateLruProcessInternalLSP(ProcessRecord app, long now, int index, int lruSeq, String what, Object obj, ProcessRecord srcApp) { private int offerLruProcessInternalLSP(ProcessRecord app, long now, String what, Object obj, ProcessRecord srcApp) { app.setLastActivityTime(now); if (app.hasActivitiesOrRecentTasks()) { // Don't want to touch dependent processes that are hosting activities. return index; return -1; } int lrui = mLruProcesses.lastIndexOf(app); final int lrui = mLruProcesses.lastIndexOf(app); if (lrui < 0) { Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " + what + " " + obj + " from " + srcApp); return index; } return lrui; } /** * This method is called after the indices array is populated by the indices offered by * {@link #offerLruProcessInternalLSP} to actually move the processes to the desired locations * in the LRU list. Since the indices array is a SparseBooleanArray, the indices are sorted * and this allows us to preserve the previous order of the processes relative to each other. * Key of the indices array holds the current index of the process in the LRU list and the value * is a boolean indicating whether the process is an activity process or not. Activity processes * are moved to the nextActivityIndex and non-activity processes are moved to the nextIndex * positions, which are provided by the caller. * * @param indices The indices of the processes to move. * @param nextActivityIndex The next index to insert an activity process. * @param nextIndex The next index to insert a non-activity process. */ @GuardedBy({"mService", "mProcLock"}) private void completeLruProcessInternalLSP(SparseBooleanArray indices, int nextActivityIndex, int nextIndex) { for (int i = indices.size() - 1; i >= 0; i--) { final int lrui = indices.keyAt(i); if (lrui < 0) { // Rest of the indices are invalid, we can return early. return; } final boolean isActivity = indices.valueAt(i); int index = isActivity ? nextActivityIndex : nextIndex; if (lrui >= index) { // Don't want to cause this to move dependent processes *back* in the // list as if they were less frequently used. return index; } if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) { // Don't want to touch dependent processes that are hosting activities. return index; continue; } mLruProcesses.remove(lrui); if (index > 0) { final ProcessRecord app = mLruProcesses.remove(lrui); index--; } if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index + " in LRU list: " + app); mLruProcesses.add(index, app); app.setLruSeq(lruSeq); return index; app.setLruSeq(mLruSeq); if (isActivity) { nextActivityIndex = index; } else { nextIndex = index; } } } /** Loading Loading @@ -4058,6 +4084,15 @@ public final class ProcessList { app.setLruSeq(mLruSeq); // Key of the indices array holds the current index of the process in the LRU list and the // value is a boolean indicating whether the process is an activity process or not. // Activity processes will be moved to the nextActivityIndex and non-activity processes will // be moved to the nextIndex positions when completeLruProcessInternalLSP is called. // Since SparseBooleanArray's keys are sorted, we'll be able to keep the existing order of // the processes relative to each other after the move. final SparseBooleanArray indices = new SparseBooleanArray(psr.numberOfConnections() + app.mProviders.numberOfProviderConnections()); // If the app is currently using a content provider or service, // bump those processes as well. for (int j = psr.numberOfConnections() - 1; j >= 0; j--) { Loading @@ -4069,16 +4104,12 @@ public final class ProcessList { && !cr.binding.service.app.isPersistent()) { if (cr.binding.service.app.mServices.hasClientActivities()) { if (nextActivityIndex >= 0) { nextActivityIndex = updateLruProcessInternalLSP(cr.binding.service.app, now, nextActivityIndex, mLruSeq, "service connection", cr, app); indices.append(offerLruProcessInternalLSP(cr.binding.service.app, now, "service connection", cr, app), true); } } else { nextIndex = updateLruProcessInternalLSP(cr.binding.service.app, now, nextIndex, mLruSeq, "service connection", cr, app); indices.append(offerLruProcessInternalLSP(cr.binding.service.app, now, "service connection", cr, app), false); } } } Loading @@ -4086,10 +4117,11 @@ public final class ProcessList { for (int j = ppr.numberOfProviderConnections() - 1; j >= 0; j--) { ContentProviderRecord cpr = ppr.getProviderConnectionAt(j).provider; if (cpr.proc != null && cpr.proc.getLruSeq() != mLruSeq && !cpr.proc.isPersistent()) { nextIndex = updateLruProcessInternalLSP(cpr.proc, now, nextIndex, mLruSeq, "provider reference", cpr, app); indices.append(offerLruProcessInternalLSP(cpr.proc, now, "provider reference", cpr, app), false); } } completeLruProcessInternalLSP(indices, nextActivityIndex, nextIndex); } @GuardedBy(anyOf = {"mService", "mProcLock"}) Loading Loading
services/core/java/com/android/server/am/ProcessList.java +63 −31 Original line number Diff line number Diff line Loading @@ -3629,42 +3629,68 @@ public final class ProcessList { } @GuardedBy({"mService", "mProcLock"}) private int updateLruProcessInternalLSP(ProcessRecord app, long now, int index, int lruSeq, String what, Object obj, ProcessRecord srcApp) { private int offerLruProcessInternalLSP(ProcessRecord app, long now, String what, Object obj, ProcessRecord srcApp) { app.setLastActivityTime(now); if (app.hasActivitiesOrRecentTasks()) { // Don't want to touch dependent processes that are hosting activities. return index; return -1; } int lrui = mLruProcesses.lastIndexOf(app); final int lrui = mLruProcesses.lastIndexOf(app); if (lrui < 0) { Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " + what + " " + obj + " from " + srcApp); return index; } return lrui; } /** * This method is called after the indices array is populated by the indices offered by * {@link #offerLruProcessInternalLSP} to actually move the processes to the desired locations * in the LRU list. Since the indices array is a SparseBooleanArray, the indices are sorted * and this allows us to preserve the previous order of the processes relative to each other. * Key of the indices array holds the current index of the process in the LRU list and the value * is a boolean indicating whether the process is an activity process or not. Activity processes * are moved to the nextActivityIndex and non-activity processes are moved to the nextIndex * positions, which are provided by the caller. * * @param indices The indices of the processes to move. * @param nextActivityIndex The next index to insert an activity process. * @param nextIndex The next index to insert a non-activity process. */ @GuardedBy({"mService", "mProcLock"}) private void completeLruProcessInternalLSP(SparseBooleanArray indices, int nextActivityIndex, int nextIndex) { for (int i = indices.size() - 1; i >= 0; i--) { final int lrui = indices.keyAt(i); if (lrui < 0) { // Rest of the indices are invalid, we can return early. return; } final boolean isActivity = indices.valueAt(i); int index = isActivity ? nextActivityIndex : nextIndex; if (lrui >= index) { // Don't want to cause this to move dependent processes *back* in the // list as if they were less frequently used. return index; } if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) { // Don't want to touch dependent processes that are hosting activities. return index; continue; } mLruProcesses.remove(lrui); if (index > 0) { final ProcessRecord app = mLruProcesses.remove(lrui); index--; } if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index + " in LRU list: " + app); mLruProcesses.add(index, app); app.setLruSeq(lruSeq); return index; app.setLruSeq(mLruSeq); if (isActivity) { nextActivityIndex = index; } else { nextIndex = index; } } } /** Loading Loading @@ -4058,6 +4084,15 @@ public final class ProcessList { app.setLruSeq(mLruSeq); // Key of the indices array holds the current index of the process in the LRU list and the // value is a boolean indicating whether the process is an activity process or not. // Activity processes will be moved to the nextActivityIndex and non-activity processes will // be moved to the nextIndex positions when completeLruProcessInternalLSP is called. // Since SparseBooleanArray's keys are sorted, we'll be able to keep the existing order of // the processes relative to each other after the move. final SparseBooleanArray indices = new SparseBooleanArray(psr.numberOfConnections() + app.mProviders.numberOfProviderConnections()); // If the app is currently using a content provider or service, // bump those processes as well. for (int j = psr.numberOfConnections() - 1; j >= 0; j--) { Loading @@ -4069,16 +4104,12 @@ public final class ProcessList { && !cr.binding.service.app.isPersistent()) { if (cr.binding.service.app.mServices.hasClientActivities()) { if (nextActivityIndex >= 0) { nextActivityIndex = updateLruProcessInternalLSP(cr.binding.service.app, now, nextActivityIndex, mLruSeq, "service connection", cr, app); indices.append(offerLruProcessInternalLSP(cr.binding.service.app, now, "service connection", cr, app), true); } } else { nextIndex = updateLruProcessInternalLSP(cr.binding.service.app, now, nextIndex, mLruSeq, "service connection", cr, app); indices.append(offerLruProcessInternalLSP(cr.binding.service.app, now, "service connection", cr, app), false); } } } Loading @@ -4086,10 +4117,11 @@ public final class ProcessList { for (int j = ppr.numberOfProviderConnections() - 1; j >= 0; j--) { ContentProviderRecord cpr = ppr.getProviderConnectionAt(j).provider; if (cpr.proc != null && cpr.proc.getLruSeq() != mLruSeq && !cpr.proc.isPersistent()) { nextIndex = updateLruProcessInternalLSP(cpr.proc, now, nextIndex, mLruSeq, "provider reference", cpr, app); indices.append(offerLruProcessInternalLSP(cpr.proc, now, "provider reference", cpr, app), false); } } completeLruProcessInternalLSP(indices, nextActivityIndex, nextIndex); } @GuardedBy(anyOf = {"mService", "mProcLock"}) Loading