From 1e38382b542f5cef9957a89692b02c55a3dd351c Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Fri, 10 Apr 2015 14:02:33 -0700 Subject: Fixes to idle alarm scheduling, package importance. - Add new API to ask the activity manager what the current importance of a particular package name is (along with a few new useful importance levels). - Fix my last alarm manager change to actually execute the alarms we have now decided should run even while we are idle. Change-Id: I1f14712b4e390770d53b185c96a1b36f6aadd687 --- api/current.txt | 8 +- api/system-current.txt | 8 +- cmds/am/src/com/android/commands/am/Am.java | 15 +++ core/java/android/app/ActivityManager.java | 93 ++++++++++++----- core/java/android/app/ActivityManagerNative.java | 115 +++++++++++++++++---- core/java/android/app/IActivityManager.java | 11 +- core/java/android/os/BatteryStats.java | 10 +- .../service/voice/VoiceInteractionSession.java | 17 ++- .../voice/VoiceInteractionSessionService.java | 25 +++++ .../com/android/internal/os/BatteryStatsImpl.java | 27 +++++ .../com/android/server/AlarmManagerService.java | 43 ++++---- .../android/server/am/ActivityManagerService.java | 64 ++++++++++-- .../com/android/server/am/BatteryStatsService.java | 16 ++- .../server/job/controllers/AppIdleController.java | 20 ++-- 14 files changed, 384 insertions(+), 88 deletions(-) diff --git a/api/current.txt b/api/current.txt index 87cd2d6..028c0ca 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3555,6 +3555,7 @@ package android.app { method public int getMemoryClass(); method public void getMemoryInfo(android.app.ActivityManager.MemoryInfo); method public static void getMyMemoryState(android.app.ActivityManager.RunningAppProcessInfo); + method public int getPackageImportance(java.lang.String); method public android.os.Debug.MemoryInfo[] getProcessMemoryInfo(int[]); method public java.util.List getProcessesInErrorState(); method public deprecated java.util.List getRecentTasks(int, int) throws java.lang.SecurityException; @@ -3647,9 +3648,11 @@ package android.app { field public static final int IMPORTANCE_BACKGROUND = 400; // 0x190 field public static final int IMPORTANCE_EMPTY = 500; // 0x1f4 field public static final int IMPORTANCE_FOREGROUND = 100; // 0x64 + field public static final int IMPORTANCE_FOREGROUND_SERVICE = 125; // 0x7d field public static final int IMPORTANCE_GONE = 1000; // 0x3e8 field public static final int IMPORTANCE_PERCEPTIBLE = 130; // 0x82 field public static final int IMPORTANCE_SERVICE = 300; // 0x12c + field public static final int IMPORTANCE_TOP_SLEEPING = 150; // 0x96 field public static final int IMPORTANCE_VISIBLE = 200; // 0xc8 field public static final int REASON_PROVIDER_IN_USE = 1; // 0x1 field public static final int REASON_SERVICE_IN_USE = 2; // 0x2 @@ -28640,7 +28643,7 @@ package android.service.voice { field public static final int START_WITH_SCREENSHOT = 2; // 0x2 } - public abstract class VoiceInteractionSession implements android.view.KeyEvent.Callback { + public abstract class VoiceInteractionSession implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback { ctor public VoiceInteractionSession(android.content.Context); ctor public VoiceInteractionSession(android.content.Context, android.os.Handler); method public void finish(); @@ -28656,6 +28659,7 @@ package android.service.voice { method public abstract void onCommand(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.String, android.os.Bundle); method public void onCompleteVoice(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle); method public void onComputeInsets(android.service.voice.VoiceInteractionSession.Insets); + method public void onConfigurationChanged(android.content.res.Configuration); method public abstract void onConfirm(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle); method public void onCreate(android.os.Bundle, int); method public android.view.View onCreateContentView(); @@ -28668,10 +28672,12 @@ package android.service.voice { method public boolean onKeyLongPress(int, android.view.KeyEvent); method public boolean onKeyMultiple(int, int, android.view.KeyEvent); method public boolean onKeyUp(int, android.view.KeyEvent); + method public void onLowMemory(); method public abstract void onPickOption(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle); method public void onShow(android.os.Bundle, int); method public void onTaskFinished(android.content.Intent, int); method public void onTaskStarted(android.content.Intent, int); + method public void onTrimMemory(int); method public void setContentView(android.view.View); method public void setKeepAwake(boolean); method public void setTheme(int); diff --git a/api/system-current.txt b/api/system-current.txt index 9e635bf..c1bc9d3 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3644,6 +3644,7 @@ package android.app { method public int getMemoryClass(); method public void getMemoryInfo(android.app.ActivityManager.MemoryInfo); method public static void getMyMemoryState(android.app.ActivityManager.RunningAppProcessInfo); + method public int getPackageImportance(java.lang.String); method public android.os.Debug.MemoryInfo[] getProcessMemoryInfo(int[]); method public java.util.List getProcessesInErrorState(); method public deprecated java.util.List getRecentTasks(int, int) throws java.lang.SecurityException; @@ -3736,9 +3737,11 @@ package android.app { field public static final int IMPORTANCE_BACKGROUND = 400; // 0x190 field public static final int IMPORTANCE_EMPTY = 500; // 0x1f4 field public static final int IMPORTANCE_FOREGROUND = 100; // 0x64 + field public static final int IMPORTANCE_FOREGROUND_SERVICE = 125; // 0x7d field public static final int IMPORTANCE_GONE = 1000; // 0x3e8 field public static final int IMPORTANCE_PERCEPTIBLE = 130; // 0x82 field public static final int IMPORTANCE_SERVICE = 300; // 0x12c + field public static final int IMPORTANCE_TOP_SLEEPING = 150; // 0x96 field public static final int IMPORTANCE_VISIBLE = 200; // 0xc8 field public static final int REASON_PROVIDER_IN_USE = 1; // 0x1 field public static final int REASON_SERVICE_IN_USE = 2; // 0x2 @@ -30736,7 +30739,7 @@ package android.service.voice { field public static final int START_WITH_SCREENSHOT = 2; // 0x2 } - public abstract class VoiceInteractionSession implements android.view.KeyEvent.Callback { + public abstract class VoiceInteractionSession implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback { ctor public VoiceInteractionSession(android.content.Context); ctor public VoiceInteractionSession(android.content.Context, android.os.Handler); method public void finish(); @@ -30752,6 +30755,7 @@ package android.service.voice { method public abstract void onCommand(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.String, android.os.Bundle); method public void onCompleteVoice(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle); method public void onComputeInsets(android.service.voice.VoiceInteractionSession.Insets); + method public void onConfigurationChanged(android.content.res.Configuration); method public abstract void onConfirm(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle); method public void onCreate(android.os.Bundle, int); method public android.view.View onCreateContentView(); @@ -30764,10 +30768,12 @@ package android.service.voice { method public boolean onKeyLongPress(int, android.view.KeyEvent); method public boolean onKeyMultiple(int, int, android.view.KeyEvent); method public boolean onKeyUp(int, android.view.KeyEvent); + method public void onLowMemory(); method public abstract void onPickOption(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle); method public void onShow(android.os.Bundle, int); method public void onTaskFinished(android.content.Intent, int); method public void onTaskStarted(android.content.Intent, int); + method public void onTrimMemory(int); method public void setContentView(android.view.View); method public void setKeepAwake(boolean); method public void setTheme(int); diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 908d46e..fa28143 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -124,6 +124,7 @@ public class Am extends BaseCommand { " am restart\n" + " am idle-maintenance\n" + " am screen-compat [on|off] \n" + + " am package-importance \n" + " am to-uri [INTENT]\n" + " am to-intent-uri [INTENT]\n" + " am to-app-uri [INTENT]\n" + @@ -233,6 +234,8 @@ public class Am extends BaseCommand { "\n" + "am screen-compat: control screen compatibility mode of .\n" + "\n" + + "am package-importance: print current importance of .\n" + + "\n" + "am to-uri: print the given Intent specification as a URI.\n" + "\n" + "am to-intent-uri: print the given Intent specification as an intent: URI.\n" + @@ -365,6 +368,8 @@ public class Am extends BaseCommand { runIdleMaintenance(); } else if (op.equals("screen-compat")) { runScreenCompat(); + } else if (op.equals("package-importance")) { + runPackageImportance(); } else if (op.equals("to-uri")) { runToUri(0); } else if (op.equals("to-intent-uri")) { @@ -1604,6 +1609,16 @@ public class Am extends BaseCommand { } while (packageName != null); } + private void runPackageImportance() throws Exception { + String packageName = nextArgRequired(); + try { + int procState = mAm.getPackageProcessState(packageName); + System.out.println( + ActivityManager.RunningAppProcessInfo.procStateToImportance(procState)); + } catch (RemoteException e) { + } + } + private void runToUri(int flags) throws Exception { Intent intent = makeIntent(UserHandle.USER_CURRENT); System.out.println(intent.toUri(flags)); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 2b35cd4..51ececc 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -2010,27 +2010,47 @@ public class ActivityManager { public int lastTrimLevel; /** - * Constant for {@link #importance}: this process is running the - * foreground UI. + * Constant for {@link #importance}: This process is running the + * foreground UI; that is, it is the thing currently at the top of the screen + * that the user is interacting with. */ public static final int IMPORTANCE_FOREGROUND = 100; /** - * Constant for {@link #importance}: this process is running something + * Constant for {@link #importance}: This process is running a foreground + * service, for example to perform music playback even while the user is + * not immediately in the app. This generally indicates that the process + * is doing something the user actively cares about. + */ + public static final int IMPORTANCE_FOREGROUND_SERVICE = 125; + + /** + * Constant for {@link #importance}: This process is running the foreground + * UI, but the device is asleep so it is not visible to the user. This means + * the user is not really aware of the process, because they can not see or + * interact with it, but it is quite important because it what they expect to + * return to once unlocking the device. + */ + public static final int IMPORTANCE_TOP_SLEEPING = 150; + + /** + * Constant for {@link #importance}: This process is running something * that is actively visible to the user, though not in the immediate - * foreground. + * foreground. This may be running a window that is behind the current + * foreground (so paused and with its state saved, not interacting with + * the user, but visible to them to some degree); it may also be running + * other services under the system's control that it inconsiders important. */ public static final int IMPORTANCE_VISIBLE = 200; /** - * Constant for {@link #importance}: this process is running something - * that is considered to be actively perceptible to the user. An - * example would be an application performing background music playback. + * Constant for {@link #importance}: This process is not something the user + * is directly aware of, but is otherwise perceptable to them to some degree. */ public static final int IMPORTANCE_PERCEPTIBLE = 130; /** - * Constant for {@link #importance}: this process is running an + * Constant for {@link #importance}: This process is running an * application that can not save its state, and thus can't be killed * while in the background. * @hide @@ -2038,42 +2058,51 @@ public class ActivityManager { public static final int IMPORTANCE_CANT_SAVE_STATE = 170; /** - * Constant for {@link #importance}: this process is contains services - * that should remain running. + * Constant for {@link #importance}: This process is contains services + * that should remain running. These are background services apps have + * started, not something the user is aware of, so they may be killed by + * the system relatively freely (though it is generally desired that they + * stay running as long as they want to). */ public static final int IMPORTANCE_SERVICE = 300; /** - * Constant for {@link #importance}: this process process contains + * Constant for {@link #importance}: This process process contains * background code that is expendable. */ public static final int IMPORTANCE_BACKGROUND = 400; /** - * Constant for {@link #importance}: this process is empty of any + * Constant for {@link #importance}: This process is empty of any * actively running code. */ public static final int IMPORTANCE_EMPTY = 500; /** - * Constant for {@link #importance}: this process does not exist. + * Constant for {@link #importance}: This process does not exist. */ public static final int IMPORTANCE_GONE = 1000; /** @hide */ public static int procStateToImportance(int procState) { - if (procState >= ActivityManager.PROCESS_STATE_HOME) { - return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; - } else if (procState >= ActivityManager.PROCESS_STATE_SERVICE) { - return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; - } else if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { - return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; - } else if (procState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { - return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; - } else if (procState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { - return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; + if (procState == PROCESS_STATE_NONEXISTENT) { + return IMPORTANCE_GONE; + } else if (procState >= PROCESS_STATE_HOME) { + return IMPORTANCE_BACKGROUND; + } else if (procState >= PROCESS_STATE_SERVICE) { + return IMPORTANCE_SERVICE; + } else if (procState > PROCESS_STATE_HEAVY_WEIGHT) { + return IMPORTANCE_CANT_SAVE_STATE; + } else if (procState >= PROCESS_STATE_IMPORTANT_BACKGROUND) { + return IMPORTANCE_PERCEPTIBLE; + } else if (procState >= PROCESS_STATE_IMPORTANT_FOREGROUND) { + return IMPORTANCE_VISIBLE; + } else if (procState >= PROCESS_STATE_TOP_SLEEPING) { + return IMPORTANCE_TOP_SLEEPING; + } else if (procState >= PROCESS_STATE_FOREGROUND_SERVICE) { + return IMPORTANCE_FOREGROUND_SERVICE; } else { - return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; + return IMPORTANCE_FOREGROUND; } } @@ -2253,6 +2282,22 @@ public class ActivityManager { } /** + * Return the importance of a given package name, based on the processes that are + * currently running. The return value is one of the importance constants defined + * in {@link RunningAppProcessInfo}, giving you the highest importance of all the + * processes that this package has code running inside of. If there are no processes + * running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned. + */ + public int getPackageImportance(String packageName) { + try { + int procState = ActivityManagerNative.getDefault().getPackageProcessState(packageName); + return RunningAppProcessInfo.procStateToImportance(procState); + } catch (RemoteException e) { + return RunningAppProcessInfo.IMPORTANCE_GONE; + } + } + + /** * Return global memory state information for the calling process. This * does not fill in all fields of the {@link RunningAppProcessInfo}. The * only fields that will be filled in are diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index f63d13c..256d87d 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -106,9 +106,24 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM } } - static public void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg) { + static public void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg, + String tag) { try { - getDefault().noteWakeupAlarm(ps.getTarget(), sourceUid, sourcePkg); + getDefault().noteWakeupAlarm(ps.getTarget(), sourceUid, sourcePkg, tag); + } catch (RemoteException ex) { + } + } + + static public void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) { + try { + getDefault().noteAlarmStart(ps.getTarget(), sourceUid, tag); + } catch (RemoteException ex) { + } + } + + static public void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) { + try { + getDefault().noteAlarmFinish(ps.getTarget(), sourceUid, tag); } catch (RemoteException ex) { } } @@ -1375,7 +1390,30 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM data.readStrongBinder()); int sourceUid = data.readInt(); String sourcePkg = data.readString(); - noteWakeupAlarm(is, sourceUid, sourcePkg); + String tag = data.readString(); + noteWakeupAlarm(is, sourceUid, sourcePkg, tag); + reply.writeNoException(); + return true; + } + + case NOTE_ALARM_START_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IIntentSender is = IIntentSender.Stub.asInterface( + data.readStrongBinder()); + int sourceUid = data.readInt(); + String tag = data.readString(); + noteAlarmStart(is, sourceUid, tag); + reply.writeNoException(); + return true; + } + + case NOTE_ALARM_FINISH_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IIntentSender is = IIntentSender.Stub.asInterface( + data.readStrongBinder()); + int sourceUid = data.readInt(); + String tag = data.readString(); + noteAlarmFinish(is, sourceUid, tag); reply.writeNoException(); return true; } @@ -2461,6 +2499,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } + + case GET_PACKAGE_PROCESS_STATE_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + String pkg = data.readString(); + int res = getPackageProcessState(pkg); + reply.writeNoException(); + reply.writeInt(res); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -3304,7 +3351,7 @@ class ActivityManagerProxy implements IActivityManager data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(stackBoxId); r.writeToParcel(data, 0); - mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -3360,7 +3407,7 @@ class ActivityManagerProxy implements IActivityManager Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(stackId); - mRemote.transact(SET_FOCUSED_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + mRemote.transact(SET_FOCUSED_STACK_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -3384,7 +3431,7 @@ class ActivityManagerProxy implements IActivityManager Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(listener.asBinder()); - mRemote.transact(REGISTER_TASK_STACK_LISTENER_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + mRemote.transact(REGISTER_TASK_STACK_LISTENER_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -4214,16 +4261,37 @@ class ActivityManagerProxy implements IActivityManager mRemote.transact(ENTER_SAFE_MODE_TRANSACTION, data, null, 0); data.recycle(); } - public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) + public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(sender.asBinder()); data.writeInt(sourceUid); data.writeString(sourcePkg); + data.writeString(tag); mRemote.transact(NOTE_WAKEUP_ALARM_TRANSACTION, data, null, 0); data.recycle(); } + public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) + throws RemoteException { + Parcel data = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(sender.asBinder()); + data.writeInt(sourceUid); + data.writeString(tag); + mRemote.transact(NOTE_ALARM_START_TRANSACTION, data, null, 0); + data.recycle(); + } + public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) + throws RemoteException { + Parcel data = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(sender.asBinder()); + data.writeInt(sourceUid); + data.writeString(tag); + mRemote.transact(NOTE_ALARM_FINISH_TRANSACTION, data, null, 0); + data.recycle(); + } public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -5486,7 +5554,7 @@ class ActivityManagerProxy implements IActivityManager data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); values.writeToParcel(data, 0); - mRemote.transact(SET_TASK_DESCRIPTION_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + mRemote.transact(SET_TASK_DESCRIPTION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -5499,7 +5567,7 @@ class ActivityManagerProxy implements IActivityManager data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(taskId); data.writeInt(resizeable ? 1 : 0); - mRemote.transact(SET_TASK_RESIZEABLE_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + mRemote.transact(SET_TASK_RESIZEABLE_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -5513,7 +5581,7 @@ class ActivityManagerProxy implements IActivityManager data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(taskId); r.writeToParcel(data, 0); - mRemote.transact(RESIZE_TASK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + mRemote.transact(RESIZE_TASK_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -5545,7 +5613,7 @@ class ActivityManagerProxy implements IActivityManager data.writeInt(1); data.writeBundle(options.toBundle()); } - mRemote.transact(START_IN_PLACE_ANIMATION_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + mRemote.transact(START_IN_PLACE_ANIMATION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -5586,8 +5654,7 @@ class ActivityManagerProxy implements IActivityManager Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); - mRemote.transact(BACKGROUND_RESOURCES_RELEASED_TRANSACTION, data, reply, - IBinder.FLAG_ONEWAY); + mRemote.transact(BACKGROUND_RESOURCES_RELEASED_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -5599,8 +5666,7 @@ class ActivityManagerProxy implements IActivityManager Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); - mRemote.transact(NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION, data, reply, - IBinder.FLAG_ONEWAY); + mRemote.transact(NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -5612,8 +5678,7 @@ class ActivityManagerProxy implements IActivityManager Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); - mRemote.transact(NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION, data, reply, - IBinder.FLAG_ONEWAY); + mRemote.transact(NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -5703,10 +5768,24 @@ class ActivityManagerProxy implements IActivityManager data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(userId); data.writeStringArray(packages); - mRemote.transact(UPDATE_LOCK_TASK_PACKAGES_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + mRemote.transact(UPDATE_LOCK_TASK_PACKAGES_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + + @Override + public int getPackageProcessState(String packageName) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeString(packageName); + mRemote.transact(GET_PACKAGE_PROCESS_STATE_TRANSACTION, data, reply, 0); reply.readException(); + int res = reply.readInt(); data.recycle(); reply.recycle(); + return res; } private IBinder mRemote; diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 4a1d6ff..59de281 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -262,7 +262,11 @@ public interface IActivityManager extends IInterface { public void enterSafeMode() throws RemoteException; - public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) + public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) + throws RemoteException; + public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) + throws RemoteException; + public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) throws RemoteException; public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException; @@ -490,6 +494,8 @@ public interface IActivityManager extends IInterface { throws RemoteException; public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException; + public int getPackageProcessState(String packageName) throws RemoteException; + /* * Private non-Binder interfaces */ @@ -825,4 +831,7 @@ public interface IActivityManager extends IInterface { int DUMP_HEAP_FINISHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+288; int SET_VOICE_KEEP_AWAKE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+289; int UPDATE_LOCK_TASK_PACKAGES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+290; + int NOTE_ALARM_START_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+291; + int NOTE_ALARM_FINISH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+292; + int GET_PACKAGE_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+293; } diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index c7edb1a..7c5ddee 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -1135,8 +1135,10 @@ public abstract class BatteryStats implements Parcelable { public static final int EVENT_PACKAGE_INSTALLED = 0x000c; // Event for a package being uninstalled. public static final int EVENT_PACKAGE_UNINSTALLED = 0x000d; + // Event for a package being uninstalled. + public static final int EVENT_ALARM = 0x000e; // Number of event types. - public static final int EVENT_COUNT = 0x000e; + public static final int EVENT_COUNT = 0x000f; // Mask to extract out only the type part of the event. public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH); @@ -1158,6 +1160,8 @@ public abstract class BatteryStats implements Parcelable { EVENT_USER_FOREGROUND | EVENT_FLAG_START; public static final int EVENT_USER_FOREGROUND_FINISH = EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH; + public static final int EVENT_ALARM_START = EVENT_ALARM | EVENT_FLAG_START; + public static final int EVENT_ALARM_FINISH = EVENT_ALARM | EVENT_FLAG_FINISH; // For CMD_EVENT. public int eventCode; @@ -1789,12 +1793,12 @@ public abstract class BatteryStats implements Parcelable { public static final String[] HISTORY_EVENT_NAMES = new String[] { "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn", - "motion", "active", "pkginst", "pkgunin" + "motion", "active", "pkginst", "pkgunin", "alarm" }; public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] { "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn", - "Esm", "Eac", "Epi", "Epu" + "Esm", "Eac", "Epi", "Epu", "Eal" }; /** diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index 20d7079..71b7f76 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -20,8 +20,10 @@ import android.app.AssistStructure; import android.app.Dialog; import android.app.Instrumentation; import android.app.VoiceInteractor; +import android.content.ComponentCallbacks2; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Rect; @@ -65,7 +67,8 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; * when done. It can also initiate voice interactions with applications by calling * {@link #startVoiceActivity}

. */ -public abstract class VoiceInteractionSession implements KeyEvent.Callback { +public abstract class VoiceInteractionSession implements KeyEvent.Callback, + ComponentCallbacks2 { static final String TAG = "VoiceInteractionSession"; static final boolean DEBUG = true; @@ -855,6 +858,18 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { hide(); } + @Override + public void onConfigurationChanged(Configuration newConfig) { + } + + @Override + public void onLowMemory() { + } + + @Override + public void onTrimMemory(int level) { + } + /** * Compute the interesting insets into your UI. The default implementation * sets {@link Insets#contentInsets outInsets.contentInsets.top} to the height diff --git a/core/java/android/service/voice/VoiceInteractionSessionService.java b/core/java/android/service/voice/VoiceInteractionSessionService.java index 008d55f..8f988f3 100644 --- a/core/java/android/service/voice/VoiceInteractionSessionService.java +++ b/core/java/android/service/voice/VoiceInteractionSessionService.java @@ -19,6 +19,7 @@ package android.service.voice; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.os.Looper; @@ -76,6 +77,30 @@ public abstract class VoiceInteractionSessionService extends Service { return mInterface.asBinder(); } + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (mSession != null) { + mSession.onConfigurationChanged(newConfig); + } + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + if (mSession != null) { + mSession.onLowMemory(); + } + } + + @Override + public void onTrimMemory(int level) { + super.onTrimMemory(level); + if (mSession != null) { + mSession.onTrimMemory(level); + } + } + void doNewSession(IBinder token, Bundle args, int startFlags) { if (mSession != null) { mSession.doDestroy(); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index fbb2dfc..87605f6 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -2692,6 +2692,32 @@ public final class BatteryStatsImpl extends BatteryStats { addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); } + public void noteAlarmStartLocked(String name, int uid) { + if (!mRecordAllHistory) { + return; + } + uid = mapUid(uid); + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_START, name, uid, 0)) { + return; + } + addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid); + } + + public void noteAlarmFinishLocked(String name, int uid) { + if (!mRecordAllHistory) { + return; + } + uid = mapUid(uid); + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) { + return; + } + addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid); + } + private void requestWakelockCpuUpdate() { if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); @@ -2709,6 +2735,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!enabled) { // Clear out any existing state. mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); + mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); // Record the currently running processes as stopping, now that we are no // longer tracking them. HashMap active = mActiveEvents.getStateForEvent( diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 34e8b78..9f80fd8 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -99,6 +99,7 @@ class AlarmManagerService extends SystemService { static final boolean DEBUG_BATCH = localLOGV || false; static final boolean DEBUG_VALIDATE = localLOGV || false; static final boolean DEBUG_ALARM_CLOCK = localLOGV || false; + static final boolean RECORD_ALARMS_IN_HISTORY = true; static final int ALARM_EVENT = 1; static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; @@ -1345,15 +1346,6 @@ class AlarmManagerService extends SystemService { } void rescheduleKernelAlarmsLocked() { - if (mPendingIdleUntil != null) { - // If we have a pending "idle until" alarm, we will just blindly wait until - // it is time for that alarm to go off. We don't want to wake up for any - // other reasons. - mNextWakeup = mNextNonWakeup = mPendingIdleUntil.whenElapsed; - setLocked(ELAPSED_REALTIME_WAKEUP, mNextWakeup); - setLocked(ELAPSED_REALTIME, mNextNonWakeup); - return; - } // Schedule the next upcoming wakeup alarm. If there is a deliverable batch // prior to that which contains no wakeups, we schedule that as well. long nextNonWakeup = 0; @@ -1574,13 +1566,6 @@ class AlarmManagerService extends SystemService { boolean triggerAlarmsLocked(ArrayList triggerList, final long nowELAPSED, final long nowRTC) { boolean hasWakeup = false; - if (mPendingIdleUntil != null) { - // If we have a pending "idle until" alarm, don't trigger any alarms - // until we are past the idle period. - if (nowELAPSED < mPendingIdleUntil.whenElapsed) { - return false; - } - } // batches are temporally sorted, so we need only pull from the // start of the list until we either empty it or hit a batch // that is not yet deliverable @@ -1816,6 +1801,17 @@ class AlarmManagerService extends SystemService { if (localLOGV) { Slog.v(TAG, "sending alarm " + alarm); } + if (RECORD_ALARMS_IN_HISTORY) { + if (alarm.workSource != null && alarm.workSource.size() > 0) { + for (int wi=0; wi 0) { + for (int wi=0; wi=0; i--) { + final ProcessRecord proc = mLruProcesses.get(i); + if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT + || procState > proc.setProcState) { + boolean found = false; + for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) { + if (proc.pkgList.keyAt(j).equals(packageName)) { + procState = proc.setProcState; + found = true; + } + } + if (proc.pkgDeps != null && !found) { + for (int j=proc.pkgDeps.size()-1; j>=0; j--) { + if (proc.pkgDeps.valueAt(j).equals(packageName)) { + procState = proc.setProcState; + break; + } + } + } + } + } + } + return procState; + } + private void dispatchProcessesChanged() { int N; synchronized (this) { @@ -10501,15 +10529,11 @@ public final class ActivityManagerService extends ActivityManagerNative Context.WINDOW_SERVICE)).addView(v, lp); } - public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { + public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) { if (!(sender instanceof PendingIntentRecord)) { return; } final PendingIntentRecord rec = (PendingIntentRecord)sender; - final String tag; - synchronized (this) { - tag = getTagForIntentSenderLocked(rec, "*walarm*:"); - } final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); synchronized (stats) { if (mBatteryStatsService.isOnBattery()) { @@ -10524,6 +10548,34 @@ public final class ActivityManagerService extends ActivityManagerNative } } + public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) { + if (!(sender instanceof PendingIntentRecord)) { + return; + } + final PendingIntentRecord rec = (PendingIntentRecord)sender; + final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); + synchronized (stats) { + mBatteryStatsService.enforceCallingPermission(); + int MY_UID = Binder.getCallingUid(); + int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; + mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid); + } + } + + public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) { + if (!(sender instanceof PendingIntentRecord)) { + return; + } + final PendingIntentRecord rec = (PendingIntentRecord)sender; + final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); + synchronized (stats) { + mBatteryStatsService.enforceCallingPermission(); + int MY_UID = Binder.getCallingUid(); + int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; + mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid); + } + } + public boolean killPids(int[] pids, String pReason, boolean secure) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("killPids only available to the system"); diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index ed108c2..bfc4fc7 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -315,6 +315,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } + public void noteAlarmStart(String name, int uid) { + enforceCallingPermission(); + synchronized (mStats) { + mStats.noteAlarmStartLocked(name, uid); + } + } + + public void noteAlarmFinish(String name, int uid) { + enforceCallingPermission(); + synchronized (mStats) { + mStats.noteAlarmFinishLocked(name, uid); + } + } + public void noteStartWakelock(int uid, int pid, String name, String historyName, int type, boolean unimportantForLogging) { enforceCallingPermission(); @@ -884,7 +898,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub pw.println(" Enable or disable a running option. Option state is not saved across boots."); pw.println(" Options are:"); pw.println(" full-history: include additional detailed events in battery history:"); - pw.println(" wake_lock_in and proc events"); + pw.println(" wake_lock_in, alarms and proc events"); pw.println(" no-auto-reset: don't automatically reset stats when unplugged"); } diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java index 8a9f3e1..23d5c05 100644 --- a/services/core/java/com/android/server/job/controllers/AppIdleController.java +++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java @@ -49,16 +49,12 @@ public class AppIdleController extends StateController private static volatile AppIdleController sController; final ArrayList mTrackedTasks = new ArrayList(); private final UsageStatsManagerInternal mUsageStatsInternal; - private final BatteryManagerInternal mBatteryManagerInternal; + private final BatteryManager mBatteryManager; private boolean mPluggedIn; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { - int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0); - // TODO: Allow any charger type - onPluggedIn((plugged & BatteryManager.BATTERY_PLUGGED_AC) != 0); - } + onPluggedIn(mBatteryManager.isCharging()); } }; @@ -74,23 +70,19 @@ public class AppIdleController extends StateController private AppIdleController(StateChangedListener stateChangedListener, Context context) { super(stateChangedListener, context); mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class); - mBatteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class); - mPluggedIn = isPowered(); + mBatteryManager = context.getSystemService(BatteryManager.class); + mPluggedIn = mBatteryManager.isCharging(); mUsageStatsInternal.addAppIdleStateChangeListener(this); registerReceivers(); } private void registerReceivers() { // Monitor battery charging state - IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING); + filter.addAction(BatteryManager.ACTION_DISCHARGING); mContext.registerReceiver(mReceiver, filter); } - private boolean isPowered() { - // TODO: Allow any charger type - return mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_AC); - } - @Override public void maybeStartTrackingJob(JobStatus jobStatus) { synchronized (mTrackedTasks) { -- cgit v1.1