am 8e3f2954: Merge "Update power manager to track uid state like netstats." into mnc-dev
* commit '8e3f29540db56d02a45966344133d6144c81e7c5': Update power manager to track uid state like netstats.
This commit is contained in:
@@ -84,6 +84,7 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/app/job/IJobScheduler.aidl \
|
||||
core/java/android/app/job/IJobService.aidl \
|
||||
core/java/android/app/ITransientNotification.aidl \
|
||||
core/java/android/app/IUidObserver.aidl \
|
||||
core/java/android/app/IUiAutomationConnection.aidl \
|
||||
core/java/android/app/IUiModeManager.aidl \
|
||||
core/java/android/app/IUserSwitchObserver.aidl \
|
||||
|
||||
@@ -1970,6 +1970,22 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
return true;
|
||||
}
|
||||
|
||||
case REGISTER_UID_OBSERVER_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
IUidObserver observer = IUidObserver.Stub.asInterface(
|
||||
data.readStrongBinder());
|
||||
registerUidObserver(observer);
|
||||
return true;
|
||||
}
|
||||
|
||||
case UNREGISTER_UID_OBSERVER_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
IUidObserver observer = IUidObserver.Stub.asInterface(
|
||||
data.readStrongBinder());
|
||||
unregisterUidObserver(observer);
|
||||
return true;
|
||||
}
|
||||
|
||||
case GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION:
|
||||
{
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
@@ -5077,6 +5093,28 @@ class ActivityManagerProxy implements IActivityManager
|
||||
reply.recycle();
|
||||
}
|
||||
|
||||
public void registerUidObserver(IUidObserver observer) throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
data.writeStrongBinder(observer != null ? observer.asBinder() : null);
|
||||
mRemote.transact(REGISTER_UID_OBSERVER_TRANSACTION, data, reply, 0);
|
||||
reply.readException();
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
}
|
||||
|
||||
public void unregisterUidObserver(IUidObserver observer) throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
data.writeStrongBinder(observer != null ? observer.asBinder() : null);
|
||||
mRemote.transact(UNREGISTER_UID_OBSERVER_TRANSACTION, data, reply, 0);
|
||||
reply.readException();
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
}
|
||||
|
||||
public boolean isIntentSenderTargetedToPackage(IIntentSender sender) throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
|
||||
@@ -387,6 +387,9 @@ public interface IActivityManager extends IInterface {
|
||||
public void registerProcessObserver(IProcessObserver observer) throws RemoteException;
|
||||
public void unregisterProcessObserver(IProcessObserver observer) throws RemoteException;
|
||||
|
||||
public void registerUidObserver(IUidObserver observer) throws RemoteException;
|
||||
public void unregisterUidObserver(IUidObserver observer) throws RemoteException;
|
||||
|
||||
public boolean isIntentSenderTargetedToPackage(IIntentSender sender) throws RemoteException;
|
||||
|
||||
public boolean isIntentSenderAnActivity(IIntentSender sender) throws RemoteException;
|
||||
@@ -844,4 +847,6 @@ public interface IActivityManager extends IInterface {
|
||||
int UPDATE_DEVICE_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+295;
|
||||
int UPDATE_PREFERRED_SETUP_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+296;
|
||||
int KEYGUARD_GOING_AWAY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+297;
|
||||
int REGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+298;
|
||||
int UNREGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+299;
|
||||
}
|
||||
|
||||
23
core/java/android/app/IUidObserver.aidl
Normal file
23
core/java/android/app/IUidObserver.aidl
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 android.app;
|
||||
|
||||
/** {@hide} */
|
||||
oneway interface IUidObserver {
|
||||
void onUidStateChanged(int uid, int procState);
|
||||
void onUidGone(int uid);
|
||||
}
|
||||
@@ -136,4 +136,8 @@ public abstract class PowerManagerInternal {
|
||||
public abstract void setDeviceIdleMode(boolean enabled);
|
||||
|
||||
public abstract void setDeviceIdleWhitelist(int[] appids);
|
||||
|
||||
public abstract void updateUidProcState(int uid, int procState);
|
||||
|
||||
public abstract void uidGone(int uid);
|
||||
}
|
||||
|
||||
@@ -133,6 +133,24 @@ public class SparseArray<E> implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Removes the mapping from the specified key, if there was any, returning the old value.
|
||||
*/
|
||||
public E removeReturnOld(int key) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i >= 0) {
|
||||
if (mValues[i] != DELETED) {
|
||||
final E old = (E) mValues[i];
|
||||
mValues[i] = DELETED;
|
||||
mGarbage = true;
|
||||
return old;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for {@link #delete(int)}.
|
||||
*/
|
||||
|
||||
@@ -39,14 +39,16 @@ public class ProcessMap<E> {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void remove(String name, int uid) {
|
||||
public E remove(String name, int uid) {
|
||||
SparseArray<E> uids = mMap.get(name);
|
||||
if (uids != null) {
|
||||
uids.remove(uid);
|
||||
final E old = uids.removeReturnOld(uid);
|
||||
if (uids.size() == 0) {
|
||||
mMap.remove(name);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ArrayMap<String, SparseArray<E>> getMap() {
|
||||
|
||||
@@ -71,6 +71,7 @@ class ActivityManagerDebugConfig {
|
||||
static final boolean DEBUG_TASKS = DEBUG_ALL || false;
|
||||
static final boolean DEBUG_THUMBNAILS = DEBUG_ALL || false;
|
||||
static final boolean DEBUG_TRANSITION = DEBUG_ALL || false;
|
||||
static final boolean DEBUG_UID_OBSERVERS = DEBUG_ALL || false;
|
||||
static final boolean DEBUG_URI_PERMISSION = DEBUG_ALL || false;
|
||||
static final boolean DEBUG_USER_LEAVING = DEBUG_ALL || false;
|
||||
static final boolean DEBUG_VISIBILITY = DEBUG_ALL || false;
|
||||
@@ -104,6 +105,8 @@ class ActivityManagerDebugConfig {
|
||||
static final String POSTFIX_TASKS = (APPEND_CATEGORY_NAME) ? "_Tasks" : "";
|
||||
static final String POSTFIX_THUMBNAILS = (APPEND_CATEGORY_NAME) ? "_Thumbnails" : "";
|
||||
static final String POSTFIX_TRANSITION = (APPEND_CATEGORY_NAME) ? "_Transition" : "";
|
||||
static final String POSTFIX_UID_OBSERVERS = (APPEND_CATEGORY_NAME)
|
||||
? "_UidObservers" : "";
|
||||
static final String POSTFIX_URI_PERMISSION = (APPEND_CATEGORY_NAME) ? "_UriPermission" : "";
|
||||
static final String POSTFIX_USER_LEAVING = (APPEND_CATEGORY_NAME) ? "_UserLeaving" : "";
|
||||
static final String POSTFIX_VISIBILITY = (APPEND_CATEGORY_NAME) ? "_Visibility" : "";
|
||||
|
||||
@@ -129,6 +129,7 @@ import android.app.INotificationManager;
|
||||
import android.app.IProcessObserver;
|
||||
import android.app.IServiceConnection;
|
||||
import android.app.IStopUserCallback;
|
||||
import android.app.IUidObserver;
|
||||
import android.app.IUiAutomationConnection;
|
||||
import android.app.IUserSwitchObserver;
|
||||
import android.app.Instrumentation;
|
||||
@@ -253,7 +254,6 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
public final class ActivityManagerService extends ActivityManagerNative
|
||||
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
|
||||
|
||||
private static final String USER_DATA_DIR = "/data/user/";
|
||||
// File that stores last updated system version and called preboot receivers
|
||||
static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
|
||||
|
||||
@@ -278,6 +278,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
|
||||
private static final String TAG_STACK = TAG + POSTFIX_STACK;
|
||||
private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
|
||||
private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
|
||||
private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
|
||||
private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
|
||||
|
||||
@@ -654,10 +655,15 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
*/
|
||||
long mPreviousProcessVisibleTime;
|
||||
|
||||
/**
|
||||
* Track all uids that have actively running processes.
|
||||
*/
|
||||
final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
|
||||
|
||||
/**
|
||||
* Which uses have been started, so are allowed to run code.
|
||||
*/
|
||||
final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
|
||||
final SparseArray<UserStartedState> mStartedUsers = new SparseArray<>();
|
||||
|
||||
/**
|
||||
* LRU list of history of current users. Most recently current is at the end.
|
||||
@@ -1022,6 +1028,11 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
*/
|
||||
private IVoiceInteractionSession mRunningVoice;
|
||||
|
||||
/**
|
||||
* For some direct access we need to power manager.
|
||||
*/
|
||||
PowerManagerInternal mLocalPowerManager;
|
||||
|
||||
/**
|
||||
* We want to hold a wake lock while running a voice interaction session, since
|
||||
* this may happen with the screen off and we need to keep the CPU running to
|
||||
@@ -1174,7 +1185,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
|
||||
final long[] mTmpLong = new long[1];
|
||||
|
||||
static class ProcessChangeItem {
|
||||
static final class ProcessChangeItem {
|
||||
static final int CHANGE_ACTIVITIES = 1<<0;
|
||||
static final int CHANGE_PROCESS_STATE = 1<<1;
|
||||
int changes;
|
||||
@@ -1184,14 +1195,17 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
boolean foregroundActivities;
|
||||
}
|
||||
|
||||
final RemoteCallbackList<IProcessObserver> mProcessObservers
|
||||
= new RemoteCallbackList<IProcessObserver>();
|
||||
final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
|
||||
ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
|
||||
|
||||
final ArrayList<ProcessChangeItem> mPendingProcessChanges
|
||||
= new ArrayList<ProcessChangeItem>();
|
||||
final ArrayList<ProcessChangeItem> mAvailProcessChanges
|
||||
= new ArrayList<ProcessChangeItem>();
|
||||
final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
|
||||
final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
|
||||
|
||||
final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
|
||||
UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
|
||||
|
||||
final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
|
||||
final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Runtime CPU use collection thread. This object's lock is used to
|
||||
@@ -1316,6 +1330,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
|
||||
static final int DELETE_DUMPHEAP_MSG = 52;
|
||||
static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
|
||||
static final int DISPATCH_UIDS_CHANGED = 54;
|
||||
|
||||
static final int FIRST_ACTIVITY_STACK_MSG = 100;
|
||||
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
|
||||
@@ -1538,6 +1553,19 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
d.dismiss();
|
||||
break;
|
||||
}
|
||||
case DISPATCH_PROCESSES_CHANGED: {
|
||||
dispatchProcessesChanged();
|
||||
break;
|
||||
}
|
||||
case DISPATCH_PROCESS_DIED: {
|
||||
final int pid = msg.arg1;
|
||||
final int uid = msg.arg2;
|
||||
dispatchProcessDied(pid, uid);
|
||||
break;
|
||||
}
|
||||
case DISPATCH_UIDS_CHANGED: {
|
||||
dispatchUidsChanged();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1723,16 +1751,6 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
|
||||
}
|
||||
} break;
|
||||
case DISPATCH_PROCESSES_CHANGED: {
|
||||
dispatchProcessesChanged();
|
||||
break;
|
||||
}
|
||||
case DISPATCH_PROCESS_DIED: {
|
||||
final int pid = msg.arg1;
|
||||
final int uid = msg.arg2;
|
||||
dispatchProcessDied(pid, uid);
|
||||
break;
|
||||
}
|
||||
case REPORT_MEM_USAGE_MSG: {
|
||||
final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
|
||||
Thread thread = new Thread() {
|
||||
@@ -2091,7 +2109,6 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
app.pid = MY_PID;
|
||||
app.maxAdj = ProcessList.SYSTEM_ADJ;
|
||||
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
|
||||
mProcessNames.put(app.processName, app.uid, app);
|
||||
synchronized (mPidsSelfLocked) {
|
||||
mPidsSelfLocked.put(app.pid, app);
|
||||
}
|
||||
@@ -2343,6 +2360,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
public void initPowerManagement() {
|
||||
mStackSupervisor.initPowerManagement();
|
||||
mBatteryStatsService.initPowerManagement();
|
||||
mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
|
||||
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
|
||||
mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
|
||||
mVoiceWakeLock.setReferenceCounted(false);
|
||||
@@ -3073,10 +3091,6 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
return null;
|
||||
}
|
||||
app.crashHandler = crashHandler;
|
||||
mProcessNames.put(processName, app.uid, app);
|
||||
if (isolated) {
|
||||
mIsolatedProcesses.put(app.uid, app);
|
||||
}
|
||||
checkTime(startTime, "startProcess: done creating new process record");
|
||||
} else {
|
||||
// If this is a new package in the process, add the package to the list
|
||||
@@ -3562,7 +3576,6 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
mActiveProcessChanges = new ProcessChangeItem[N];
|
||||
}
|
||||
mPendingProcessChanges.toArray(mActiveProcessChanges);
|
||||
mAvailProcessChanges.addAll(mPendingProcessChanges);
|
||||
mPendingProcessChanges.clear();
|
||||
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
|
||||
"*** Delivering " + N + " process changes");
|
||||
@@ -3595,6 +3608,12 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
}
|
||||
mProcessObservers.finishBroadcast();
|
||||
|
||||
synchronized (this) {
|
||||
for (int j=0; j<N; j++) {
|
||||
mAvailProcessChanges.add(mActiveProcessChanges[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchProcessDied(int pid, int uid) {
|
||||
@@ -3612,6 +3631,67 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
mProcessObservers.finishBroadcast();
|
||||
}
|
||||
|
||||
private void dispatchUidsChanged() {
|
||||
int N;
|
||||
synchronized (this) {
|
||||
N = mPendingUidChanges.size();
|
||||
if (mActiveUidChanges.length < N) {
|
||||
mActiveUidChanges = new UidRecord.ChangeItem[N];
|
||||
}
|
||||
for (int i=0; i<N; i++) {
|
||||
final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
|
||||
mActiveUidChanges[i] = change;
|
||||
change.uidRecord.pendingChange = null;
|
||||
change.uidRecord = null;
|
||||
}
|
||||
mPendingUidChanges.clear();
|
||||
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
|
||||
"*** Delivering " + N + " uid changes");
|
||||
}
|
||||
|
||||
if (mLocalPowerManager != null) {
|
||||
for (int j=0; j<N; j++) {
|
||||
UidRecord.ChangeItem item = mActiveUidChanges[j];
|
||||
if (item.gone) {
|
||||
mLocalPowerManager.uidGone(item.uid);
|
||||
} else {
|
||||
mLocalPowerManager.updateUidProcState(item.uid, item.processState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int i = mUidObservers.beginBroadcast();
|
||||
while (i > 0) {
|
||||
i--;
|
||||
final IUidObserver observer = mUidObservers.getBroadcastItem(i);
|
||||
if (observer != null) {
|
||||
try {
|
||||
for (int j=0; j<N; j++) {
|
||||
UidRecord.ChangeItem item = mActiveUidChanges[j];
|
||||
if (item.gone) {
|
||||
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
|
||||
"UID gone uid=" + item.uid);
|
||||
observer.onUidGone(item.uid);
|
||||
} else {
|
||||
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
|
||||
"UID CHANGED uid=" + item.uid
|
||||
+ ": " + item.processState);
|
||||
observer.onUidStateChanged(item.uid, item.processState);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
mUidObservers.finishBroadcast();
|
||||
|
||||
synchronized (this) {
|
||||
for (int j=0; j<N; j++) {
|
||||
mAvailUidChanges.add(mActiveUidChanges[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int startActivity(IApplicationThread caller, String callingPackage,
|
||||
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
|
||||
@@ -5623,6 +5703,47 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
return didSomething;
|
||||
}
|
||||
|
||||
private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
|
||||
ProcessRecord old = mProcessNames.remove(name, uid);
|
||||
if (old != null) {
|
||||
old.uidRecord.numProcs--;
|
||||
if (old.uidRecord.numProcs == 0) {
|
||||
// No more processes using this uid, tell clients it is gone.
|
||||
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
|
||||
"No more processes in " + old.uidRecord);
|
||||
enqueueUidChangeLocked(old.uidRecord, true);
|
||||
mActiveUids.remove(uid);
|
||||
}
|
||||
old.uidRecord = null;
|
||||
}
|
||||
mIsolatedProcesses.remove(uid);
|
||||
return old;
|
||||
}
|
||||
|
||||
private final void addProcessNameLocked(ProcessRecord proc) {
|
||||
// We shouldn't already have a process under this name, but just in case we
|
||||
// need to clean up whatever may be there now.
|
||||
ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
|
||||
if (old != null) {
|
||||
Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
|
||||
}
|
||||
UidRecord uidRec = mActiveUids.get(proc.uid);
|
||||
if (uidRec == null) {
|
||||
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);
|
||||
mActiveUids.put(proc.uid, uidRec);
|
||||
enqueueUidChangeLocked(uidRec, false);
|
||||
}
|
||||
proc.uidRecord = uidRec;
|
||||
uidRec.numProcs++;
|
||||
mProcessNames.put(proc.processName, proc.uid, proc);
|
||||
if (proc.isolated) {
|
||||
mIsolatedProcesses.put(proc.uid, proc);
|
||||
}
|
||||
}
|
||||
|
||||
private final boolean removeProcessLocked(ProcessRecord app,
|
||||
boolean callerWillRestart, boolean allowRestart, String reason) {
|
||||
final String name = app.processName;
|
||||
@@ -5630,8 +5751,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
|
||||
"Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
|
||||
|
||||
mProcessNames.remove(name, uid);
|
||||
mIsolatedProcesses.remove(app.uid);
|
||||
removeProcessNameLocked(name, uid);
|
||||
if (mHeavyWeightProcess == app) {
|
||||
mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
|
||||
mHeavyWeightProcess.userId, 0));
|
||||
@@ -5684,8 +5804,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
Slog.w(TAG, "Process " + app + " failed to attach");
|
||||
EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
|
||||
pid, app.uid, app.processName);
|
||||
mProcessNames.remove(app.processName, app.uid);
|
||||
mIsolatedProcesses.remove(app.uid);
|
||||
removeProcessNameLocked(app.processName, app.uid);
|
||||
if (mHeavyWeightProcess == app) {
|
||||
mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
|
||||
mHeavyWeightProcess.userId, 0));
|
||||
@@ -9874,7 +9993,6 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
|
||||
boolean isolated, int isolatedUid) {
|
||||
String proc = customProcess != null ? customProcess : info.processName;
|
||||
BatteryStatsImpl.Uid.Proc ps = null;
|
||||
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
|
||||
final int userId = UserHandle.getUserId(info.uid);
|
||||
int uid = info.uid;
|
||||
@@ -9909,6 +10027,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
&& (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
|
||||
r.persistent = true;
|
||||
}
|
||||
addProcessNameLocked(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -9923,10 +10042,6 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
|
||||
if (app == null) {
|
||||
app = newProcessRecordLocked(info, null, isolated, 0);
|
||||
mProcessNames.put(info.processName, app.uid, app);
|
||||
if (isolated) {
|
||||
mIsolatedProcesses.put(app.uid, app);
|
||||
}
|
||||
updateLruProcessLocked(app, false, null);
|
||||
updateOomAdjLocked();
|
||||
}
|
||||
@@ -10602,6 +10717,21 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
}
|
||||
|
||||
public void registerUidObserver(IUidObserver observer) {
|
||||
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
|
||||
"registerUidObserver()");
|
||||
synchronized (this) {
|
||||
mUidObservers.register(observer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterUidObserver(IUidObserver observer) {
|
||||
synchronized (this) {
|
||||
mUidObservers.unregister(observer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean convertFromTranslucent(IBinder token) {
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
@@ -12920,6 +13050,20 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
}
|
||||
|
||||
if (mActiveUids.size() > 0) {
|
||||
if (needSep) {
|
||||
pw.println();
|
||||
}
|
||||
pw.println(" UID states:");
|
||||
for (int i=0; i<mActiveUids.size(); i++) {
|
||||
UidRecord uidRec = mActiveUids.valueAt(i);
|
||||
pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
|
||||
pw.print(": "); pw.println(uidRec);
|
||||
}
|
||||
needSep = true;
|
||||
printedAnything = true;
|
||||
}
|
||||
|
||||
if (mLruProcesses.size() > 0) {
|
||||
if (needSep) {
|
||||
pw.println();
|
||||
@@ -15162,7 +15306,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
mAvailProcessChanges.add(item);
|
||||
}
|
||||
}
|
||||
mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
|
||||
mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
|
||||
|
||||
// If the caller is restarting this app, then leave it in its
|
||||
// current lists and let the caller take care of it.
|
||||
@@ -15173,8 +15317,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (!app.persistent || app.isolated) {
|
||||
if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
|
||||
"Removing non-persistent process during cleanup: " + app);
|
||||
mProcessNames.remove(app.processName, app.uid);
|
||||
mIsolatedProcesses.remove(app.uid);
|
||||
removeProcessNameLocked(app.processName, app.uid);
|
||||
if (mHeavyWeightProcess == app) {
|
||||
mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
|
||||
mHeavyWeightProcess.userId, 0));
|
||||
@@ -15206,7 +15349,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (index < 0) {
|
||||
ProcessList.remove(app.pid);
|
||||
}
|
||||
mProcessNames.put(app.processName, app.uid, app);
|
||||
addProcessNameLocked(app);
|
||||
startProcessLocked(app, "restart", app.processName);
|
||||
return true;
|
||||
} else if (app.pid > 0 && app.pid != MY_PID) {
|
||||
@@ -18289,7 +18432,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (NA > 0) {
|
||||
item = mAvailProcessChanges.remove(NA-1);
|
||||
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
|
||||
"Retreiving available item: " + item);
|
||||
"Retrieving available item: " + item);
|
||||
} else {
|
||||
item = new ProcessChangeItem();
|
||||
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
|
||||
@@ -18301,7 +18444,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (mPendingProcessChanges.size() == 0) {
|
||||
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
|
||||
"*** Enqueueing dispatch processes changed!");
|
||||
mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
|
||||
mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
|
||||
}
|
||||
mPendingProcessChanges.add(item);
|
||||
}
|
||||
@@ -18320,6 +18463,31 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
return success;
|
||||
}
|
||||
|
||||
private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
|
||||
if (uidRec.pendingChange == null) {
|
||||
if (mPendingUidChanges.size() == 0) {
|
||||
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
|
||||
"*** Enqueueing dispatch uid changed!");
|
||||
mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED).sendToTarget();
|
||||
}
|
||||
final int NA = mAvailUidChanges.size();
|
||||
if (NA > 0) {
|
||||
uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
|
||||
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
|
||||
"Retrieving available item: " + uidRec.pendingChange);
|
||||
} else {
|
||||
uidRec.pendingChange = new UidRecord.ChangeItem();
|
||||
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
|
||||
"Allocating new item: " + uidRec.pendingChange);
|
||||
}
|
||||
uidRec.pendingChange.uidRecord = uidRec;
|
||||
uidRec.pendingChange.uid = uidRec.uid;
|
||||
mPendingUidChanges.add(uidRec.pendingChange);
|
||||
}
|
||||
uidRec.pendingChange.gone = gone;
|
||||
uidRec.pendingChange.processState = uidRec.setProcState;
|
||||
}
|
||||
|
||||
private void maybeUpdateUsageStats(ProcessRecord app) {
|
||||
if (DEBUG_USAGE_STATS) {
|
||||
Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
|
||||
@@ -18463,6 +18631,14 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
|
||||
}
|
||||
|
||||
// Reset state in all uid records.
|
||||
for (int i=mActiveUids.size()-1; i>=0; i--) {
|
||||
final UidRecord uidRec = mActiveUids.valueAt(i);
|
||||
if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
|
||||
"Starting update of " + uidRec);
|
||||
uidRec.reset();
|
||||
}
|
||||
|
||||
mAdjSeq++;
|
||||
mNewNumServiceProcs = 0;
|
||||
mNewNumAServiceProcs = 0;
|
||||
@@ -18610,6 +18786,12 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
// good to avoid having whatever code was running in them
|
||||
// left sitting around after no longer needed.
|
||||
app.kill("isolated not needed", true);
|
||||
} else {
|
||||
// Keeping this process, update its uid.
|
||||
final UidRecord uidRec = app.uidRecord;
|
||||
if (uidRec != null && uidRec.curProcState > app.curProcState) {
|
||||
uidRec.curProcState = app.curProcState;
|
||||
}
|
||||
}
|
||||
|
||||
if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
|
||||
@@ -18805,6 +18987,18 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
|
||||
}
|
||||
|
||||
// Update from any uid changes.
|
||||
for (int i=mActiveUids.size()-1; i>=0; i--) {
|
||||
final UidRecord uidRec = mActiveUids.valueAt(i);
|
||||
if (uidRec.setProcState != uidRec.curProcState) {
|
||||
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
|
||||
"Changes in " + uidRec + ": proc state from " + uidRec.setProcState
|
||||
+ " to " + uidRec.curProcState);
|
||||
uidRec.setProcState = uidRec.curProcState;
|
||||
enqueueUidChangeLocked(uidRec, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (mProcessStats.shouldWriteNowLocked(now)) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override public void run() {
|
||||
|
||||
@@ -62,8 +62,8 @@ final class ProcessRecord {
|
||||
final int userId; // user of process.
|
||||
final String processName; // name of the process
|
||||
// List of packages running in the process
|
||||
final ArrayMap<String, ProcessStats.ProcessStateHolder> pkgList
|
||||
= new ArrayMap<String, ProcessStats.ProcessStateHolder>();
|
||||
final ArrayMap<String, ProcessStats.ProcessStateHolder> pkgList = new ArrayMap<>();
|
||||
UidRecord uidRecord; // overall state of process's uid.
|
||||
ArraySet<String> pkgDeps; // additional packages we have a dependency on
|
||||
IApplicationThread thread; // the actual proc... may be null only if
|
||||
// 'persistent' is true (in which case we
|
||||
@@ -142,24 +142,20 @@ final class ProcessRecord {
|
||||
Object adjTarget; // Debugging: target component impacting oom_adj.
|
||||
Runnable crashHandler; // Optional local handler to be invoked in the process crash.
|
||||
|
||||
// contains HistoryRecord objects
|
||||
final ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
|
||||
// all activities running in the process
|
||||
final ArrayList<ActivityRecord> activities = new ArrayList<>();
|
||||
// all ServiceRecord running in this process
|
||||
final ArraySet<ServiceRecord> services = new ArraySet<ServiceRecord>();
|
||||
final ArraySet<ServiceRecord> services = new ArraySet<>();
|
||||
// services that are currently executing code (need to remain foreground).
|
||||
final ArraySet<ServiceRecord> executingServices
|
||||
= new ArraySet<ServiceRecord>();
|
||||
final ArraySet<ServiceRecord> executingServices = new ArraySet<>();
|
||||
// All ConnectionRecord this process holds
|
||||
final ArraySet<ConnectionRecord> connections
|
||||
= new ArraySet<ConnectionRecord>();
|
||||
final ArraySet<ConnectionRecord> connections = new ArraySet<>();
|
||||
// all IIntentReceivers that are registered from this process.
|
||||
final ArraySet<ReceiverList> receivers = new ArraySet<ReceiverList>();
|
||||
final ArraySet<ReceiverList> receivers = new ArraySet<>();
|
||||
// class (String) -> ContentProviderRecord
|
||||
final ArrayMap<String, ContentProviderRecord> pubProviders
|
||||
= new ArrayMap<String, ContentProviderRecord>();
|
||||
final ArrayMap<String, ContentProviderRecord> pubProviders = new ArrayMap<>();
|
||||
// All ContentProviderRecord process is using
|
||||
final ArrayList<ContentProviderConnection> conProviders
|
||||
= new ArrayList<ContentProviderConnection>();
|
||||
final ArrayList<ContentProviderConnection> conProviders = new ArrayList<>();
|
||||
|
||||
boolean execServicesFg; // do we need to be executing services in the foreground?
|
||||
boolean persistent; // always keep this application running?
|
||||
|
||||
62
services/core/java/com/android/server/am/UidRecord.java
Normal file
62
services/core/java/com/android/server/am/UidRecord.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.am;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.os.UserHandle;
|
||||
|
||||
/**
|
||||
* Overall information about a uid that has actively running processes.
|
||||
*/
|
||||
public final class UidRecord {
|
||||
final int uid;
|
||||
int curProcState;
|
||||
int setProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
|
||||
int numProcs;
|
||||
|
||||
static final class ChangeItem {
|
||||
UidRecord uidRecord;
|
||||
int uid;
|
||||
boolean gone;
|
||||
int processState;
|
||||
}
|
||||
|
||||
ChangeItem pendingChange;
|
||||
|
||||
public UidRecord(int _uid) {
|
||||
uid = _uid;
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append("UidRecord{");
|
||||
sb.append(Integer.toHexString(System.identityHashCode(this)));
|
||||
sb.append(' ');
|
||||
UserHandle.formatUid(sb, uid);
|
||||
sb.append(' ');
|
||||
sb.append(ProcessList.makeProcStateString(curProcState));
|
||||
sb.append(" / ");
|
||||
sb.append(numProcs);
|
||||
sb.append(" procs}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,7 @@ import android.app.AppOpsManager;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.INotificationManager;
|
||||
import android.app.IProcessObserver;
|
||||
import android.app.IUidObserver;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.usage.UsageStatsManagerInternal;
|
||||
@@ -153,10 +154,8 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.server.AppOpsService;
|
||||
import com.android.server.DeviceIdleController;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemConfig;
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
@@ -294,9 +293,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
||||
/** Set of currently active {@link Notification} tags. */
|
||||
private final ArraySet<String> mActiveNotifs = new ArraySet<String>();
|
||||
|
||||
/** Foreground at both UID and PID granularity. */
|
||||
/** Foreground at UID granularity. */
|
||||
final SparseIntArray mUidState = new SparseIntArray();
|
||||
final SparseArray<SparseIntArray> mUidPidState = new SparseArray<>();
|
||||
|
||||
/** The current maximum process state that we are considering to be foreground. */
|
||||
private int mCurForegroundState = ActivityManager.PROCESS_STATE_TOP;
|
||||
@@ -411,7 +409,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
||||
updateScreenOn();
|
||||
|
||||
try {
|
||||
mActivityManager.registerProcessObserver(mProcessObserver);
|
||||
mActivityManager.registerUidObserver(mUidObserver);
|
||||
mNetworkManager.registerObserver(mAlertObserver);
|
||||
} catch (RemoteException e) {
|
||||
// ignored; both services live in system_server
|
||||
@@ -477,40 +475,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
||||
|
||||
}
|
||||
|
||||
private IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
|
||||
@Override
|
||||
public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProcessStateChanged(int pid, int uid, int procState) {
|
||||
private IUidObserver mUidObserver = new IUidObserver.Stub() {
|
||||
@Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
|
||||
synchronized (mRulesLock) {
|
||||
// because a uid can have multiple pids running inside, we need to
|
||||
// remember all pid states and summarize foreground at uid level.
|
||||
|
||||
// record foreground for this specific pid
|
||||
SparseIntArray pidState = mUidPidState.get(uid);
|
||||
if (pidState == null) {
|
||||
pidState = new SparseIntArray(2);
|
||||
mUidPidState.put(uid, pidState);
|
||||
}
|
||||
pidState.put(pid, procState);
|
||||
computeUidStateLocked(uid);
|
||||
updateUidStateLocked(uid, procState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProcessDied(int pid, int uid) {
|
||||
@Override public void onUidGone(int uid) throws RemoteException {
|
||||
synchronized (mRulesLock) {
|
||||
// clear records and recompute, when they exist
|
||||
final SparseIntArray pidState = mUidPidState.get(uid);
|
||||
if (pidState != null) {
|
||||
pidState.delete(pid);
|
||||
if (pidState.size() <= 0) {
|
||||
mUidPidState.remove(uid);
|
||||
}
|
||||
computeUidStateLocked(uid);
|
||||
}
|
||||
removeUidStateLocked(uid);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1919,14 +1893,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
||||
fout.print(state);
|
||||
fout.print(state <= mCurForegroundState ? " (fg)" : " (bg)");
|
||||
|
||||
fout.print(" pids=");
|
||||
final int foregroundIndex = mUidPidState.indexOfKey(uid);
|
||||
if (foregroundIndex < 0) {
|
||||
fout.print("UNKNOWN");
|
||||
} else {
|
||||
dumpSparseIntArray(fout, mUidPidState.valueAt(foregroundIndex));
|
||||
}
|
||||
|
||||
fout.print(" rules=");
|
||||
final int rulesIndex = mUidRules.indexOfKey(uid);
|
||||
if (rulesIndex < 0) {
|
||||
@@ -1957,36 +1923,38 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
||||
}
|
||||
|
||||
/**
|
||||
* Process state of PID changed; recompute state at UID level. If
|
||||
* changed, will trigger {@link #updateRulesForUidLocked(int)}.
|
||||
* Process state of UID changed; if needed, will trigger
|
||||
* {@link #updateRulesForUidLocked(int)}.
|
||||
*/
|
||||
void computeUidStateLocked(int uid) {
|
||||
final SparseIntArray pidState = mUidPidState.get(uid);
|
||||
|
||||
// current pid is dropping foreground; examine other pids
|
||||
int uidState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
|
||||
if (pidState != null) {
|
||||
final int size = pidState.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final int state = pidState.valueAt(i);
|
||||
if (state < uidState) {
|
||||
uidState = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateUidStateLocked(int uid, int uidState) {
|
||||
final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
|
||||
if (oldUidState != uidState) {
|
||||
// state changed, push updated rules
|
||||
mUidState.put(uid, uidState);
|
||||
final boolean oldForeground = oldUidState <= mCurForegroundState;
|
||||
final boolean newForeground = uidState <= mCurForegroundState;
|
||||
if (oldForeground != newForeground) {
|
||||
updateRulesForUidLocked(uid);
|
||||
updateRulesForUidStateChangeLocked(uid, oldUidState, uidState);
|
||||
}
|
||||
}
|
||||
|
||||
void removeUidStateLocked(int uid) {
|
||||
final int index = mUidState.indexOfKey(uid);
|
||||
if (index >= 0) {
|
||||
final int oldUidState = mUidState.valueAt(index);
|
||||
mUidState.removeAt(index);
|
||||
if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
|
||||
updateRulesForUidStateChangeLocked(uid, oldUidState,
|
||||
ActivityManager.PROCESS_STATE_CACHED_EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateRulesForUidStateChangeLocked(int uid, int oldUidState, int newUidState) {
|
||||
final boolean oldForeground = oldUidState <= mCurForegroundState;
|
||||
final boolean newForeground = newUidState <= mCurForegroundState;
|
||||
if (oldForeground != newForeground) {
|
||||
updateRulesForUidLocked(uid);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateScreenOn() {
|
||||
synchronized (mRulesLock) {
|
||||
try {
|
||||
@@ -2381,16 +2349,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private static void dumpSparseIntArray(PrintWriter fout, SparseIntArray value) {
|
||||
fout.print("[");
|
||||
final int size = value.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
fout.print(value.keyAt(i) + "=" + value.valueAt(i));
|
||||
if (i < size - 1) fout.print(",");
|
||||
}
|
||||
fout.print("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void factoryReset(String subscriber) {
|
||||
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.power;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.util.SparseIntArray;
|
||||
import com.android.internal.app.IAppOpsService;
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
@@ -436,6 +438,8 @@ public final class PowerManagerService extends SystemService
|
||||
// Set of app ids that we will always respect the wake locks for.
|
||||
int[] mDeviceIdleWhitelist = new int[0];
|
||||
|
||||
private final SparseIntArray mUidState = new SparseIntArray();
|
||||
|
||||
// True if theater mode is enabled
|
||||
private boolean mTheaterModeEnabled;
|
||||
|
||||
@@ -2316,6 +2320,24 @@ public final class PowerManagerService extends SystemService
|
||||
}
|
||||
}
|
||||
|
||||
void updateUidProcStateInternal(int uid, int procState) {
|
||||
synchronized (mLock) {
|
||||
mUidState.put(uid, procState);
|
||||
if (mDeviceIdleMode) {
|
||||
updateWakeLockDisabledStatesLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uidGoneInternal(int uid) {
|
||||
synchronized (mLock) {
|
||||
mUidState.delete(uid);
|
||||
if (mDeviceIdleMode) {
|
||||
updateWakeLockDisabledStatesLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWakeLockDisabledStatesLocked() {
|
||||
boolean changed = false;
|
||||
final int numWakeLocks = mWakeLocks.size();
|
||||
@@ -2349,7 +2371,10 @@ public final class PowerManagerService extends SystemService
|
||||
// If we are in idle mode, we will ignore all partial wake locks that are
|
||||
// for application uids that are not whitelisted.
|
||||
if (appid >= Process.FIRST_APPLICATION_UID &&
|
||||
Arrays.binarySearch(mDeviceIdleWhitelist, appid) < 0) {
|
||||
Arrays.binarySearch(mDeviceIdleWhitelist, appid) < 0 &&
|
||||
mUidState.get(wakeLock.mOwnerUid,
|
||||
ActivityManager.PROCESS_STATE_CACHED_EMPTY)
|
||||
> ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
|
||||
disabled = true;
|
||||
}
|
||||
}
|
||||
@@ -2649,6 +2674,13 @@ public final class PowerManagerService extends SystemService
|
||||
pw.println("Screen off timeout: " + screenOffTimeout + " ms");
|
||||
pw.println("Screen dim duration: " + screenDimDuration + " ms");
|
||||
|
||||
pw.println();
|
||||
pw.println("UID states:");
|
||||
for (int i=0; i<mUidState.size(); i++) {
|
||||
pw.print(" UID "); UserHandle.formatUid(pw, mUidState.keyAt(i));
|
||||
pw.print(": "); pw.println(mUidState.valueAt(i));
|
||||
}
|
||||
|
||||
pw.println();
|
||||
pw.println("Wake Locks: size=" + mWakeLocks.size());
|
||||
for (WakeLock wl : mWakeLocks) {
|
||||
@@ -3451,5 +3483,15 @@ public final class PowerManagerService extends SystemService
|
||||
public void setDeviceIdleWhitelist(int[] appids) {
|
||||
setDeviceIdleWhitelistInternal(appids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUidProcState(int uid, int procState) {
|
||||
updateUidProcStateInternal(uid, procState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uidGone(int uid) {
|
||||
uidGoneInternal(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user