aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Maltsev <pavelm@google.com>2017-03-22 14:49:02 -0700
committerPavel Maltsev <pavelm@google.com>2017-03-24 17:58:01 -0700
commitddbff98a7c62b2c02dd0849ff8d6d54015a6f944 (patch)
tree56fbf582d4c530bba70cea47998e87c5c5cca957
parent5780c0cc276693707bd170e95a26c7cea0573993 (diff)
downloadCar-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.java21
-rw-r--r--service/src/com/android/car/CarPowerManagementService.java61
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);
}