use of android.util.SparseArray in project platform_frameworks_base by android.
the class SecurityControllerImpl method updateState.
private void updateState() {
// Find all users with an active VPN
SparseArray<VpnConfig> vpns = new SparseArray<>();
try {
for (UserInfo user : mUserManager.getUsers()) {
VpnConfig cfg = mConnectivityManagerService.getVpnConfig(user.id);
if (cfg == null) {
continue;
} else if (cfg.legacy) {
// Legacy VPNs should do nothing if the network is disconnected. Third-party
// VPN warnings need to continue as traffic can still go to the app.
LegacyVpnInfo legacyVpn = mConnectivityManagerService.getLegacyVpnInfo(user.id);
if (legacyVpn == null || legacyVpn.state != LegacyVpnInfo.STATE_CONNECTED) {
continue;
}
}
vpns.put(user.id, cfg);
}
} catch (RemoteException rme) {
// Roll back to previous state
Log.e(TAG, "Unable to list active VPNs", rme);
return;
}
mCurrentVpns = vpns;
}
use of android.util.SparseArray in project platform_frameworks_base by android.
the class ActivityManagerService method reportMemUsage.
void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
for (int i = 0, N = memInfos.size(); i < N; i++) {
ProcessMemInfo mi = memInfos.get(i);
infoMap.put(mi.pid, mi);
}
updateCpuStatsNow();
long[] memtrackTmp = new long[1];
final List<ProcessCpuTracker.Stats> stats;
// Get a list of Stats that have vsize > 0
synchronized (mProcessCpuTracker) {
stats = mProcessCpuTracker.getStats((st) -> {
return st.vsize > 0;
});
}
final int statsCount = stats.size();
for (int i = 0; i < statsCount; i++) {
ProcessCpuTracker.Stats st = stats.get(i);
long pss = Debug.getPss(st.pid, null, memtrackTmp);
if (pss > 0) {
if (infoMap.indexOfKey(st.pid) < 0) {
ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, ProcessList.NATIVE_ADJ, -1, "native", null);
mi.pss = pss;
mi.memtrack = memtrackTmp[0];
memInfos.add(mi);
}
}
}
long totalPss = 0;
long totalMemtrack = 0;
for (int i = 0, N = memInfos.size(); i < N; i++) {
ProcessMemInfo mi = memInfos.get(i);
if (mi.pss == 0) {
mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
mi.memtrack = memtrackTmp[0];
}
totalPss += mi.pss;
totalMemtrack += mi.memtrack;
}
Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
@Override
public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
if (lhs.oomAdj != rhs.oomAdj) {
return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
}
if (lhs.pss != rhs.pss) {
return lhs.pss < rhs.pss ? 1 : -1;
}
return 0;
}
});
StringBuilder tag = new StringBuilder(128);
StringBuilder stack = new StringBuilder(128);
tag.append("Low on memory -- ");
appendMemBucket(tag, totalPss, "total", false);
appendMemBucket(stack, totalPss, "total", true);
StringBuilder fullNativeBuilder = new StringBuilder(1024);
StringBuilder shortNativeBuilder = new StringBuilder(1024);
StringBuilder fullJavaBuilder = new StringBuilder(1024);
boolean firstLine = true;
int lastOomAdj = Integer.MIN_VALUE;
long extraNativeRam = 0;
long extraNativeMemtrack = 0;
long cachedPss = 0;
for (int i = 0, N = memInfos.size(); i < N; i++) {
ProcessMemInfo mi = memInfos.get(i);
if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
cachedPss += mi.pss;
}
if (mi.oomAdj != ProcessList.NATIVE_ADJ && (mi.oomAdj < ProcessList.SERVICE_ADJ || mi.oomAdj == ProcessList.HOME_APP_ADJ || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
if (lastOomAdj != mi.oomAdj) {
lastOomAdj = mi.oomAdj;
if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
tag.append(" / ");
}
if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
if (firstLine) {
stack.append(":");
firstLine = false;
}
stack.append("\n\t at ");
} else {
stack.append("$");
}
} else {
tag.append(" ");
stack.append("$");
}
if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
appendMemBucket(tag, mi.pss, mi.name, false);
}
appendMemBucket(stack, mi.pss, mi.name, true);
if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ && ((i + 1) >= N || memInfos.get(i + 1).oomAdj != lastOomAdj)) {
stack.append("(");
for (int k = 0; k < DUMP_MEM_OOM_ADJ.length; k++) {
if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
stack.append(DUMP_MEM_OOM_LABEL[k]);
stack.append(":");
stack.append(DUMP_MEM_OOM_ADJ[k]);
}
}
stack.append(")");
}
}
appendMemInfo(fullNativeBuilder, mi);
if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
// The short form only has native processes that are >= 512K.
if (mi.pss >= 512) {
appendMemInfo(shortNativeBuilder, mi);
} else {
extraNativeRam += mi.pss;
extraNativeMemtrack += mi.memtrack;
}
} else {
// from smaller native processes let's dump a summary of that.
if (extraNativeRam > 0) {
appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
shortNativeBuilder.append('\n');
extraNativeRam = 0;
}
appendMemInfo(fullJavaBuilder, mi);
}
}
fullJavaBuilder.append(" ");
ProcessList.appendRamKb(fullJavaBuilder, totalPss);
fullJavaBuilder.append(": TOTAL");
if (totalMemtrack > 0) {
fullJavaBuilder.append(" (");
fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
fullJavaBuilder.append(" memtrack)");
} else {
}
fullJavaBuilder.append("\n");
MemInfoReader memInfo = new MemInfoReader();
memInfo.readMemInfo();
final long[] infos = memInfo.getRawInfo();
StringBuilder memInfoBuilder = new StringBuilder(1024);
Debug.getMemInfo(infos);
memInfoBuilder.append(" MemInfo: ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
memInfoBuilder.append(" ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
memInfoBuilder.append(" ZRAM: ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
memInfoBuilder.append(" RAM, ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
memInfoBuilder.append(" swap total, ");
memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
memInfoBuilder.append(" swap free\n");
}
final long[] ksm = getKsmInfo();
if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 || ksm[KSM_VOLATILE] != 0) {
memInfoBuilder.append(" KSM: ");
memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
memInfoBuilder.append(" saved from shared ");
memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
memInfoBuilder.append("\n ");
memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
memInfoBuilder.append(" unshared; ");
memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
memInfoBuilder.append(" volatile\n");
}
memInfoBuilder.append(" Free RAM: ");
memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() + memInfo.getFreeSizeKb()));
memInfoBuilder.append("\n");
memInfoBuilder.append(" Used RAM: ");
memInfoBuilder.append(stringifyKBSize(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
memInfoBuilder.append("\n");
memInfoBuilder.append(" Lost RAM: ");
memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb() - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
memInfoBuilder.append("\n");
Slog.i(TAG, "Low on memory:");
Slog.i(TAG, shortNativeBuilder.toString());
Slog.i(TAG, fullJavaBuilder.toString());
Slog.i(TAG, memInfoBuilder.toString());
StringBuilder dropBuilder = new StringBuilder(1024);
/*
StringWriter oomSw = new StringWriter();
PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
StringWriter catSw = new StringWriter();
PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
String[] emptyArgs = new String[] { };
dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
oomPw.flush();
String oomString = oomSw.toString();
*/
dropBuilder.append("Low on memory:");
dropBuilder.append(stack);
dropBuilder.append('\n');
dropBuilder.append(fullNativeBuilder);
dropBuilder.append(fullJavaBuilder);
dropBuilder.append('\n');
dropBuilder.append(memInfoBuilder);
dropBuilder.append('\n');
/*
dropBuilder.append(oomString);
dropBuilder.append('\n');
*/
StringWriter catSw = new StringWriter();
synchronized (ActivityManagerService.this) {
PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
String[] emptyArgs = new String[] {};
catPw.println();
dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
catPw.println();
mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, false, null).dumpLocked();
catPw.println();
dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
catPw.flush();
}
dropBuilder.append(catSw.toString());
addErrorToDropBox("lowmem", null, "system_server", null, null, tag.toString(), dropBuilder.toString(), null, null);
//Slog.i(TAG, dropBuilder.toString());
synchronized (ActivityManagerService.this) {
long now = SystemClock.uptimeMillis();
if (mLastMemUsageReportTime < now) {
mLastMemUsageReportTime = now;
}
}
}
use of android.util.SparseArray in project platform_frameworks_base by android.
the class ActivityManagerService method cleanUpRemovedTaskLocked.
private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess, boolean removeFromRecents) {
if (removeFromRecents) {
mRecentTasks.remove(tr);
tr.removedFromRecents();
}
ComponentName component = tr.getBaseIntent().getComponent();
if (component == null) {
Slog.w(TAG, "No component for base intent of task: " + tr);
return;
}
// Find any running services associated with this app and stop if needed.
mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
if (!killProcess) {
return;
}
// Determine if the process(es) for this task should be killed.
final String pkg = component.getPackageName();
ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
for (int i = 0; i < pmap.size(); i++) {
SparseArray<ProcessRecord> uids = pmap.valueAt(i);
for (int j = 0; j < uids.size(); j++) {
ProcessRecord proc = uids.valueAt(j);
if (proc.userId != tr.userId) {
// Don't kill process for a different user.
continue;
}
if (proc == mHomeProcess) {
// Don't kill the home process along with tasks from the same package.
continue;
}
if (!proc.pkgList.containsKey(pkg)) {
// Don't kill process that is not associated with this task.
continue;
}
for (int k = 0; k < proc.activities.size(); k++) {
TaskRecord otherTask = proc.activities.get(k).task;
if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
// also in recents.
return;
}
}
if (proc.foregroundServices) {
// Don't kill process(es) with foreground service.
return;
}
// Add process to kill list.
procsToKill.add(proc);
}
}
// Kill the running processes.
for (int i = 0; i < procsToKill.size(); i++) {
ProcessRecord pr = procsToKill.get(i);
if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND && pr.curReceivers.isEmpty()) {
pr.kill("remove task", true);
} else {
// We delay killing processes that are not in the background or running a receiver.
pr.waitingToKill = "remove task";
}
}
}
use of android.util.SparseArray in project platform_frameworks_base by android.
the class ProcessStatsService method setMemFactorLocked.
public boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) {
mMemFactorLowered = memFactor < mLastMemOnlyState;
mLastMemOnlyState = memFactor;
if (screenOn) {
memFactor += ProcessStats.ADJ_SCREEN_ON;
}
if (memFactor != mProcessStats.mMemFactor) {
if (mProcessStats.mMemFactor != ProcessStats.STATE_NOTHING) {
mProcessStats.mMemFactorDurations[mProcessStats.mMemFactor] += now - mProcessStats.mStartTime;
}
mProcessStats.mMemFactor = memFactor;
mProcessStats.mStartTime = now;
final ArrayMap<String, SparseArray<SparseArray<ProcessStats.PackageState>>> pmap = mProcessStats.mPackages.getMap();
for (int ipkg = pmap.size() - 1; ipkg >= 0; ipkg--) {
final SparseArray<SparseArray<ProcessStats.PackageState>> uids = pmap.valueAt(ipkg);
for (int iuid = uids.size() - 1; iuid >= 0; iuid--) {
final SparseArray<ProcessStats.PackageState> vers = uids.valueAt(iuid);
for (int iver = vers.size() - 1; iver >= 0; iver--) {
final ProcessStats.PackageState pkg = vers.valueAt(iver);
final ArrayMap<String, ServiceState> services = pkg.mServices;
for (int isvc = services.size() - 1; isvc >= 0; isvc--) {
final ServiceState service = services.valueAt(isvc);
service.setMemFactor(memFactor, now);
}
}
}
}
return true;
}
return false;
}
use of android.util.SparseArray in project platform_frameworks_base by android.
the class ManagedServices method rebindServices.
/**
* Called whenever packages change, the user switches, or the secure setting
* is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
*/
private void rebindServices(boolean forceRebind) {
if (DEBUG)
Slog.d(TAG, "rebindServices");
final int[] userIds = mUserProfiles.getCurrentProfileIds();
final int nUserIds = userIds.length;
final SparseArray<ArraySet<ComponentName>> componentsByUser = new SparseArray<>();
for (int i = 0; i < nUserIds; ++i) {
componentsByUser.put(userIds[i], loadComponentNamesFromSetting(mConfig.secureSettingName, userIds[i]));
if (mConfig.secondarySettingName != null) {
componentsByUser.get(userIds[i]).addAll(loadComponentNamesFromSetting(mConfig.secondarySettingName, userIds[i]));
}
}
final ArrayList<ManagedServiceInfo> removableBoundServices = new ArrayList<>();
final SparseArray<Set<ComponentName>> toAdd = new SparseArray<>();
synchronized (mMutex) {
// Rebind to non-system services if user switched
for (ManagedServiceInfo service : mServices) {
if (!service.isSystem && !service.isGuest(this)) {
removableBoundServices.add(service);
}
}
mEnabledServicesForCurrentProfiles.clear();
mEnabledServicesPackageNames.clear();
for (int i = 0; i < nUserIds; ++i) {
// decode the list of components
final ArraySet<ComponentName> userComponents = componentsByUser.get(userIds[i]);
if (null == userComponents) {
toAdd.put(userIds[i], new ArraySet<ComponentName>());
continue;
}
final Set<ComponentName> add = new HashSet<>(userComponents);
add.removeAll(mSnoozingForCurrentProfiles);
toAdd.put(userIds[i], add);
mEnabledServicesForCurrentProfiles.addAll(userComponents);
for (int j = 0; j < userComponents.size(); j++) {
final ComponentName component = userComponents.valueAt(j);
mEnabledServicesPackageNames.add(component.getPackageName());
}
}
}
for (ManagedServiceInfo info : removableBoundServices) {
final ComponentName component = info.component;
final int oldUser = info.userid;
final Set<ComponentName> allowedComponents = toAdd.get(info.userid);
if (allowedComponents != null) {
if (allowedComponents.contains(component) && !forceRebind) {
// Already bound, don't need to bind again.
allowedComponents.remove(component);
} else {
// No longer allowed to be bound, or must rebind.
Slog.v(TAG, "disabling " + getCaption() + " for user " + oldUser + ": " + component);
unregisterService(component, oldUser);
}
}
}
for (int i = 0; i < nUserIds; ++i) {
final Set<ComponentName> add = toAdd.get(userIds[i]);
for (ComponentName component : add) {
Slog.v(TAG, "enabling " + getCaption() + " for " + userIds[i] + ": " + component);
registerService(component, userIds[i]);
}
}
mLastSeenProfileIds = userIds;
}
Aggregations