diff options
author | Jeff Brown <jeffbrown@google.com> | 2014-06-12 22:38:59 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2014-06-17 18:20:42 -0700 |
commit | 2c43c339de5aaf4fef58aa9b5ac3af48609263a8 (patch) | |
tree | a6ffedae0013f7c54483fdf9cd60de6fb6e22b46 /services/core/java | |
parent | 12758423770455f75fede0cb47d743ea18640f2f (diff) | |
download | frameworks_base-2c43c339de5aaf4fef58aa9b5ac3af48609263a8.zip frameworks_base-2c43c339de5aaf4fef58aa9b5ac3af48609263a8.tar.gz frameworks_base-2c43c339de5aaf4fef58aa9b5ac3af48609263a8.tar.bz2 |
Resolve boot time dependencies related to the power manager.
This change fixes a bug where native daemons may try to communicate
with the power manager before it was fully initialized due to a race
between publishing the binder service and completing init().
The solution was to simplify the dependencies related to the power
manager. It turns out that most services that were passed in
init are not actually needed until systemReady. What remained
was a dependency on the activity manager to check permissions for
incoming calls. So now we start activity manager first.
However, the activity manager also depends on power manager for
wakelocks. To break the cycle, we now defer initializing the activity
manager's wakelocks until after the power manager has been started.
Cleaned up a bunch of boot-time service dependencies so that we
can have better confidence that they are correctly maintained.
Bug: 13884219
Change-Id: If08e2d7ccd44e7026a72441bb6bd5afd7bb9fffe
Diffstat (limited to 'services/core/java')
6 files changed, 45 insertions, 43 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 697e1f2..6190868 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2194,6 +2194,11 @@ public final class ActivityManagerService extends ActivityManagerNative LocalServices.addService(ActivityManagerInternal.class, new LocalService()); } + public void initPowerManagement() { + mStackSupervisor.initPowerManagement(); + mBatteryStatsService.initPowerManagement(); + } + @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 66e9eb3..ed7e594 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -227,14 +227,14 @@ public final class ActivityStackSupervisor implements DisplayListener { * receivers to launch an activity and get that to run before the device * goes back to sleep. */ - final PowerManager.WakeLock mLaunchingActivity; + PowerManager.WakeLock mLaunchingActivity; /** * Set when the system is going to sleep, until we have * successfully paused the current activity and released our wake lock. * At that point the system is allowed to actually sleep. */ - final PowerManager.WakeLock mGoingToSleep; + PowerManager.WakeLock mGoingToSleep; /** Stack id of the front stack when user switched, indexed by userId. */ SparseIntArray mUserStackInFront = new SparseIntArray(2); @@ -255,12 +255,16 @@ public final class ActivityStackSupervisor implements DisplayListener { public ActivityStackSupervisor(ActivityManagerService service) { mService = service; + mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper()); + } + + /** + * At the time when the constructor runs, the power manager has not yet been + * initialized. So we initialize our wakelocks afterwards. + */ + void initPowerManagement() { PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE); mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); - mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper()); - if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { - throw new IllegalStateException("Calling must be system uid"); - } mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); mLaunchingActivity.setReferenceCounted(false); diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index eb253eb..f403d08 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -74,12 +74,19 @@ public final class BatteryStatsService extends IBatteryStats.Stub mStats.setRadioScanningTimeout(mContext.getResources().getInteger( com.android.internal.R.integer.config_radioScanningTimeout) * 1000L); + } + + /** + * At the time when the constructor runs, the power manager has not yet been + * initialized. So we initialize the low power observer later. + */ + public void initPowerManagement() { mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mPowerManagerInternal.registerLowPowerModeObserver(this); mStats.noteLowPowerMode(mPowerManagerInternal.getLowPowerModeEnabled()); (new WakeupReasonThread()).start(); - } - + } + public void shutdown() { Slog.w("BatteryStats", "Writing battery stats before shutdown..."); synchronized (mStats) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5feee50..dc76455 100755 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1248,7 +1248,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } - public static final IPackageManager main(Context context, Installer installer, + public static final PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index fb4b8f0..b25012f 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -23,6 +23,7 @@ import com.android.server.BatteryService; import com.android.server.EventLogTags; import com.android.server.LocalServices; import com.android.server.ServiceThread; +import com.android.server.am.BatteryStatsService; import com.android.server.lights.Light; import com.android.server.lights.LightsManager; import com.android.server.Watchdog; @@ -163,13 +164,14 @@ public final class PowerManagerService extends com.android.server.SystemService private static final int POWER_HINT_LOW_POWER_MODE = 5; private final Context mContext; + private final ServiceThread mHandlerThread; + private final PowerManagerHandler mHandler; + private LightsManager mLightsManager; private BatteryService mBatteryService; private DisplayManagerInternal mDisplayManagerInternal; private IBatteryStats mBatteryStats; private IAppOpsService mAppOps; - private ServiceThread mHandlerThread; - private PowerManagerHandler mHandler; private WindowManagerPolicy mPolicy; private Notifier mNotifier; private WirelessChargerDetector mWirelessChargerDetector; @@ -429,6 +431,11 @@ public final class PowerManagerService extends com.android.server.SystemService public PowerManagerService(Context context) { super(context); mContext = context; + mHandlerThread = new ServiceThread(TAG, + Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/); + mHandlerThread.start(); + mHandler = new PowerManagerHandler(mHandlerThread.getLooper()); + synchronized (mLock) { mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks"); mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display"); @@ -451,39 +458,19 @@ public final class PowerManagerService extends com.android.server.SystemService public void onStart() { publishBinderService(Context.POWER_SERVICE, new BinderService()); publishLocalService(PowerManagerInternal.class, new LocalService()); - } - - /** - * Initialize the power manager. - * Must be called before any other functions within the power manager are called. - */ - public void init(LightsManager ls, - BatteryService bs, IBatteryStats bss, - IAppOpsService appOps) { - mLightsManager = ls; - mBatteryService = bs; - mBatteryStats = bss; - mAppOps = appOps; - mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); - mHandlerThread = new ServiceThread(TAG, - Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/); - mHandlerThread.start(); - mHandler = new PowerManagerHandler(mHandlerThread.getLooper()); Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); } - void setPolicy(WindowManagerPolicy policy) { - synchronized (mLock) { - mPolicy = policy; - } - } - - public void systemReady() { + public void systemReady(BatteryService batteryService, IAppOpsService appOps) { synchronized (mLock) { mSystemReady = true; - mDreamManager = LocalServices.getService(DreamManagerInternal.class); + mBatteryService = batteryService; + mAppOps = appOps; + mDreamManager = getLocalService(DreamManagerInternal.class); + mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); + mPolicy = getLocalService(WindowManagerPolicy.class); PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting(); @@ -494,6 +481,7 @@ public final class PowerManagerService extends com.android.server.SystemService // The notifier runs on the system server's main looper so as not to interfere // with the animations and other critical functions of the power manager. + mBatteryStats = BatteryStatsService.getService(); mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats, mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mScreenOnBlocker, mPolicy); @@ -502,6 +490,8 @@ public final class PowerManagerService extends com.android.server.SystemService createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"), mHandler); mSettingsObserver = new SettingsObserver(mHandler); + + mLightsManager = getLocalService(LightsManager.class); mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION); // Initialize display power management. @@ -3076,10 +3066,5 @@ public final class PowerManagerService extends com.android.server.SystemService mLowPowerModeListeners.add(listener); } } - - @Override - public void setPolicy(WindowManagerPolicy policy) { - PowerManagerService.this.setPolicy(policy); - } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 2d8a34b..d04d668 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -766,6 +766,8 @@ public class WindowManagerService extends IWindowManager.Stub mDisplaySettings = new DisplaySettings(context); mDisplaySettings.readSettingsLocked(); + LocalServices.addService(WindowManagerPolicy.class, mPolicy); + mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG)); mFxSession = new SurfaceSession(); @@ -779,7 +781,6 @@ public class WindowManagerService extends IWindowManager.Stub mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); - mPowerManagerInternal.setPolicy(mPolicy); // TODO: register as local service instead mPowerManagerInternal.registerLowPowerModeObserver( new PowerManagerInternal.LowPowerModeListener() { @Override |