diff options
author | Pavel Maltsev <pavelm@google.com> | 2017-03-22 14:49:02 -0700 |
---|---|---|
committer | Pavel Maltsev <pavelm@google.com> | 2017-03-24 17:58:01 -0700 |
commit | ddbff98a7c62b2c02dd0849ff8d6d54015a6f944 (patch) | |
tree | 56fbf582d4c530bba70cea47998e87c5c5cca957 | |
parent | 5780c0cc276693707bd170e95a26c7cea0573993 (diff) | |
download | Car-ddbff98a7c62b2c02dd0849ff8d6d54015a6f944.tar.gz |
Respect init/release methods in Car Service
Some services have internal threads to handle events,
these threads must respect init/release calls, otherwise
we are running out of threads when car service test runs
Test: runtest -x packages/services/Car/tests/carservice_test/
Change-Id: I58b63f98b09c57f742bd9a4ceef6d77b87d9aaa1
Fix: b/36514170
-rw-r--r-- | service/src/com/android/car/AppFocusService.java | 21 | ||||
-rw-r--r-- | service/src/com/android/car/CarPowerManagementService.java | 61 |
2 files changed, 62 insertions, 20 deletions
diff --git a/service/src/com/android/car/AppFocusService.java b/service/src/com/android/car/AppFocusService.java index 5e6753357f..3db21d2800 100644 --- a/service/src/com/android/car/AppFocusService.java +++ b/service/src/com/android/car/AppFocusService.java @@ -49,21 +49,19 @@ public class AppFocusService extends IAppFocus.Stub implements CarServiceBase, /** K: appType, V: client owning it */ private final HashMap<Integer, OwnershipClientInfo> mFocusOwners = new HashMap<>(); private final Set<Integer> mActiveAppTypes = new HashSet<>(); - private final HandlerThread mHandlerThread; - private final DispatchHandler mDispatchHandler; private final CopyOnWriteArrayList<FocusOwnershipCallback> mFocusOwnershipCallbacks = new CopyOnWriteArrayList<>(); private final BinderInterfaceContainer.BinderEventHandler<IAppFocusListener> mAllBinderEventHandler = bInterface -> { /* nothing to do.*/ }; + private DispatchHandler mDispatchHandler; + private HandlerThread mHandlerThread; + public AppFocusService(Context context, SystemActivityMonitoringService systemActivityMonitoringService) { mSystemActivityMonitoringService = systemActivityMonitoringService; mAllChangeClients = new ClientHolder(mAllBinderEventHandler); mAllOwnershipClients = new OwnershipClientHolder(this); - mHandlerThread = new HandlerThread(AppFocusService.class.getSimpleName()); - mHandlerThread.start(); - mDispatchHandler = new DispatchHandler(mHandlerThread.getLooper()); } @Override @@ -212,12 +210,23 @@ public class AppFocusService extends IAppFocus.Stub implements CarServiceBase, @Override public void init() { - // nothing to do + synchronized (this) { + mHandlerThread = new HandlerThread(AppFocusService.class.getSimpleName()); + mHandlerThread.start(); + mDispatchHandler = new DispatchHandler(mHandlerThread.getLooper()); + } } @Override public void release() { synchronized (this) { + mHandlerThread.quitSafely(); + try { + mHandlerThread.join(1000); + } catch (InterruptedException e) { + Log.e(CarLog.TAG_APP_FOCUS, "Timeout while waiting for handler thread to join."); + } + mDispatchHandler = null; mAllChangeClients.clear(); mAllOwnershipClients.clear(); mFocusOwners.clear(); diff --git a/service/src/com/android/car/CarPowerManagementService.java b/service/src/com/android/car/CarPowerManagementService.java index 22f8b093cd..4eb04b46c5 100644 --- a/service/src/com/android/car/CarPowerManagementService.java +++ b/service/src/com/android/car/CarPowerManagementService.java @@ -89,8 +89,6 @@ public class CarPowerManagementService implements CarServiceBase, private final PowerHalService mHal; private final SystemInterface mSystemInterface; - private final HandlerThread mHandlerThread; - private final PowerHandler mHandler; private final CopyOnWriteArrayList<PowerServiceEventListener> mListeners = new CopyOnWriteArrayList<>(); @@ -107,6 +105,10 @@ public class CarPowerManagementService implements CarServiceBase, private long mLastSleepEntryTime; @GuardedBy("this") private final LinkedList<PowerState> mPendingPowerStates = new LinkedList<>(); + @GuardedBy("this") + private HandlerThread mHandlerThread; + @GuardedBy("this") + private PowerHandler mHandler; private final static int SHUTDOWN_POLLING_INTERVAL_MS = 2000; private final static int SHUTDOWN_EXTEND_MAX_MS = 5000; @@ -114,9 +116,6 @@ public class CarPowerManagementService implements CarServiceBase, public CarPowerManagementService(PowerHalService powerHal, SystemInterface systemInterface) { mHal = powerHal; mSystemInterface = systemInterface; - mHandlerThread = new HandlerThread(CarLog.TAG_POWER); - mHandlerThread.start(); - mHandler = new PowerHandler(mHandlerThread.getLooper()); } /** @@ -133,6 +132,12 @@ public class CarPowerManagementService implements CarServiceBase, @Override public void init() { + synchronized (this) { + mHandlerThread = new HandlerThread(CarLog.TAG_POWER); + mHandlerThread.start(); + mHandler = new PowerHandler(mHandlerThread.getLooper()); + } + mHal.setListener(this); if (mHal.isPowerStateSupported()) { mHal.sendBootComplete(); @@ -153,12 +158,20 @@ public class CarPowerManagementService implements CarServiceBase, @Override public void release() { + HandlerThread handlerThread; synchronized (this) { releaseTimerLocked(); mCurrentState = null; + mHandler.cancelAll(); + handlerThread = mHandlerThread; + } + handlerThread.quitSafely(); + try { + handlerThread.join(1000); + } catch (InterruptedException e) { + Log.e(CarLog.TAG_POWER, "Timeout while joining for handler thread to join."); } mSystemInterface.stopDisplayStateMonitoring(); - mHandler.cancelAll(); mListeners.clear(); mPowerEventProcessingHandlers.clear(); mSystemInterface.releaseAllWakeLocks(); @@ -209,6 +222,7 @@ public class CarPowerManagementService implements CarServiceBase, long now = SystemClock.elapsedRealtime(); long startTime; boolean shouldShutdown = true; + PowerHandler powerHandler; synchronized (this) { startTime = mProcessingStartTime; if (mCurrentState == null) { @@ -224,10 +238,11 @@ public class CarPowerManagementService implements CarServiceBase, return; } } + powerHandler = mHandler; } if ((startTime + processingTime) <= now) { Log.i(CarLog.TAG_POWER, "Processing all done"); - mHandler.handleProcessingComplete(shouldShutdown); + powerHandler.handleProcessingComplete(shouldShutdown); } } @@ -245,14 +260,17 @@ public class CarPowerManagementService implements CarServiceBase, @Override public void onApPowerStateChange(PowerState state) { + PowerHandler handler; synchronized (this) { mPendingPowerStates.addFirst(state); + handler = mHandler; } - mHandler.handlePowerStateChange(); + handler.handlePowerStateChange(); } private void doHandlePowerStateChange() { PowerState state = null; + PowerHandler handler; synchronized (this) { state = mPendingPowerStates.peekFirst(); mPendingPowerStates.clear(); @@ -264,8 +282,9 @@ public class CarPowerManagementService implements CarServiceBase, } // now real power change happens. Whatever was queued before should be all cancelled. releaseTimerLocked(); - mHandler.cancelProcessingComplete(); + handler = mHandler; } + handler.cancelProcessingComplete(); Log.i(CarLog.TAG_POWER, "Power state change:" + state); switch (state.mState) { @@ -366,7 +385,11 @@ public class CarPowerManagementService implements CarServiceBase, SHUTDOWN_POLLING_INTERVAL_MS); } } else { - mHandler.handleProcessingComplete(shuttingDown); + PowerHandler handler; + synchronized (this) { + handler = mHandler; + } + handler.handleProcessingComplete(shuttingDown); } } @@ -374,7 +397,11 @@ public class CarPowerManagementService implements CarServiceBase, // keep holding partial wakelock to prevent entering sleep before enterDeepSleep call // enterDeepSleep should force sleep entry even if wake lock is kept. mSystemInterface.switchToPartialWakeLock(); - mHandler.cancelProcessingComplete(); + PowerHandler handler; + synchronized (this) { + handler = mHandler; + } + handler.cancelProcessingComplete(); for (PowerServiceEventListener listener : mListeners) { listener.onSleepEntry(); } @@ -482,10 +509,14 @@ public class CarPowerManagementService implements CarServiceBase, } public void handleMainDisplayChanged(boolean on) { - mHandler.handleMainDisplayStateChange(on); + PowerHandler handler; + synchronized (this) { + handler = mHandler; + } + handler.handleMainDisplayStateChange(on); } - public Handler getHandler() { + public synchronized Handler getHandler() { return mHandler; } @@ -581,10 +612,12 @@ public class CarPowerManagementService implements CarServiceBase, public void run() { mCurrentCount++; if (mCurrentCount > mExpirationCount) { + PowerHandler handler; synchronized (CarPowerManagementService.this) { releaseTimerLocked(); + handler = mHandler; } - mHandler.handleProcessingComplete(mShutdownWhenCompleted); + handler.handleProcessingComplete(mShutdownWhenCompleted); } else { mHal.sendShutdownPostpone(SHUTDOWN_EXTEND_MAX_MS); } |