Merge "Force car service crash handling to client"
diff --git a/car-lib/src/android/car/Car.java b/car-lib/src/android/car/Car.java
index 6716a69..2d03cc9 100644
--- a/car-lib/src/android/car/Car.java
+++ b/car-lib/src/android/car/Car.java
@@ -24,6 +24,8 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.app.Activity;
+import android.app.Service;
import android.car.cluster.CarInstrumentClusterManager;
import android.car.cluster.ClusterActivityState;
import android.car.content.pm.CarPackageManager;
@@ -738,11 +740,10 @@
mConnectionState = STATE_CONNECTED;
mService = newService;
}
- if (mServiceConnectionListenerClient != null) {
- mServiceConnectionListenerClient.onServiceConnected(name, service);
- }
if (mStatusChangeCallback != null) {
mStatusChangeCallback.onLifecycleChanged(Car.this, true);
+ } else if (mServiceConnectionListenerClient != null) {
+ mServiceConnectionListenerClient.onServiceConnected(name, service);
}
}
@@ -755,11 +756,13 @@
}
handleCarDisconnectLocked();
}
- if (mServiceConnectionListenerClient != null) {
- mServiceConnectionListenerClient.onServiceDisconnected(name);
- }
if (mStatusChangeCallback != null) {
mStatusChangeCallback.onLifecycleChanged(Car.this, false);
+ } else if (mServiceConnectionListenerClient != null) {
+ mServiceConnectionListenerClient.onServiceDisconnected(name);
+ } else {
+ // This client does not handle car service restart, so should be terminated.
+ finishClient();
}
}
};
@@ -1147,12 +1150,15 @@
@Nullable
public Object getCarManager(String serviceName) {
CarManagerBase manager;
- ICar service = getICarOrThrow();
synchronized (mLock) {
+ if (mService == null) {
+ Log.w(TAG_CAR, "getCarManager not working while car service not ready");
+ return null;
+ }
manager = mServiceMap.get(serviceName);
if (manager == null) {
try {
- IBinder binder = service.getCarService(serviceName);
+ IBinder binder = mService.getCarService(serviceName);
if (binder == null) {
Log.w(TAG_CAR, "getCarManager could not get binder for service:"
+ serviceName);
@@ -1166,7 +1172,7 @@
}
mServiceMap.put(serviceName, manager);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
@@ -1182,90 +1188,145 @@
return CONNECTION_TYPE_EMBEDDED;
}
+ /** @hide */
+ Context getContext() {
+ return mContext;
+ }
+
+ /** @hide */
+ Handler getEventHandler() {
+ return mEventHandler;
+ }
+
+ /** @hide */
+ <T> T handleRemoteExceptionFromCarService(RemoteException e, T returnValue) {
+ handleRemoteExceptionFromCarService(e);
+ return returnValue;
+ }
+
+ /** @hide */
+ void handleRemoteExceptionFromCarService(RemoteException e) {
+ Log.w(TAG_CAR, "Car service has crashed", e);
+ }
+
+
+ private void finishClient() {
+ if (mContext == null) {
+ throw new IllegalStateException("Car service has crashed, null Context");
+ }
+ if (mContext instanceof Activity) {
+ Activity activity = (Activity) mContext;
+ if (!activity.isFinishing()) {
+ Log.w(TAG_CAR, "Car service crashed, client not handling it, finish Activity");
+ activity.finish();
+ }
+ return;
+ } else if (mContext instanceof Service) {
+ Service service = (Service) mContext;
+ throw new RuntimeException("Car service has crashed, client not handle it:"
+ + service.getPackageName() + "," + service.getClass().getSimpleName());
+ }
+ throw new IllegalStateException("Car service crashed, client not handling it.");
+ }
+
+ /** @hide */
+ public static <T> T handleRemoteExceptionFromCarService(Service service, RemoteException e,
+ T returnValue) {
+ handleRemoteExceptionFromCarService(service, e);
+ return returnValue;
+ }
+
+ /** @hide */
+ public static void handleRemoteExceptionFromCarService(Service service, RemoteException e) {
+ Log.w(TAG_CAR,
+ "Car service has crashed, client:" + service.getPackageName() + ","
+ + service.getClass().getSimpleName(), e);
+ service.stopSelf();
+ }
+
@Nullable
private CarManagerBase createCarManager(String serviceName, IBinder binder) {
CarManagerBase manager = null;
switch (serviceName) {
case AUDIO_SERVICE:
- manager = new CarAudioManager(binder, mContext, mEventHandler);
+ manager = new CarAudioManager(this, binder);
break;
case SENSOR_SERVICE:
- manager = new CarSensorManager(binder, mContext, mEventHandler);
+ manager = new CarSensorManager(this, binder);
break;
case INFO_SERVICE:
- manager = new CarInfoManager(binder);
+ manager = new CarInfoManager(this, binder);
break;
case APP_FOCUS_SERVICE:
- manager = new CarAppFocusManager(binder, mEventHandler);
+ manager = new CarAppFocusManager(this, binder);
break;
case PACKAGE_SERVICE:
- manager = new CarPackageManager(binder, mContext);
+ manager = new CarPackageManager(this, binder);
break;
case CAR_OCCUPANT_ZONE_SERVICE:
- manager = new CarOccupantZoneManager(binder, mContext, mEventHandler);
+ manager = new CarOccupantZoneManager(this, binder);
break;
case CAR_NAVIGATION_SERVICE:
- manager = new CarNavigationStatusManager(binder);
+ manager = new CarNavigationStatusManager(this, binder);
break;
case CABIN_SERVICE:
- manager = new CarCabinManager(binder, mContext, mEventHandler);
+ manager = new CarCabinManager(this, binder);
break;
case DIAGNOSTIC_SERVICE:
- manager = new CarDiagnosticManager(binder, mContext, mEventHandler);
+ manager = new CarDiagnosticManager(this, binder);
break;
case HVAC_SERVICE:
- manager = new CarHvacManager(binder, mContext, mEventHandler);
+ manager = new CarHvacManager(this, binder);
break;
case POWER_SERVICE:
- manager = new CarPowerManager(binder, mContext, mEventHandler);
+ manager = new CarPowerManager(this, binder);
break;
case PROJECTION_SERVICE:
- manager = new CarProjectionManager(binder, mEventHandler);
+ manager = new CarProjectionManager(this, binder);
break;
case PROPERTY_SERVICE:
- manager = new CarPropertyManager(ICarProperty.Stub.asInterface(binder),
- mEventHandler);
+ manager = new CarPropertyManager(this, ICarProperty.Stub.asInterface(binder));
break;
case VENDOR_EXTENSION_SERVICE:
- manager = new CarVendorExtensionManager(binder, mEventHandler);
+ manager = new CarVendorExtensionManager(this, binder);
break;
case CAR_INSTRUMENT_CLUSTER_SERVICE:
- manager = new CarInstrumentClusterManager(binder, mEventHandler);
+ manager = new CarInstrumentClusterManager(this, binder);
break;
case TEST_SERVICE:
/* CarTestManager exist in static library. So instead of constructing it here,
* only pass binder wrapper so that CarTestManager can be constructed outside. */
- manager = new CarTestManagerBinderWrapper(binder);
+ manager = new CarTestManagerBinderWrapper(this, binder);
break;
case VMS_SUBSCRIBER_SERVICE:
- manager = new VmsSubscriberManager(binder);
+ manager = new VmsSubscriberManager(this, binder);
break;
case BLUETOOTH_SERVICE:
- manager = new CarBluetoothManager(binder, mContext);
+ manager = new CarBluetoothManager(this, binder);
break;
case STORAGE_MONITORING_SERVICE:
- manager = new CarStorageMonitoringManager(binder, mEventHandler);
+ manager = new CarStorageMonitoringManager(this, binder);
break;
case CAR_DRIVING_STATE_SERVICE:
- manager = new CarDrivingStateManager(binder, mContext, mEventHandler);
+ manager = new CarDrivingStateManager(this, binder);
break;
case CAR_UX_RESTRICTION_SERVICE:
- manager = new CarUxRestrictionsManager(binder, mContext, mEventHandler);
+ manager = new CarUxRestrictionsManager(this, binder);
break;
case CAR_CONFIGURATION_SERVICE:
- manager = new CarConfigurationManager(binder);
+ manager = new CarConfigurationManager(this, binder);
break;
case CAR_TRUST_AGENT_ENROLLMENT_SERVICE:
- manager = new CarTrustAgentEnrollmentManager(binder, mContext, mEventHandler);
+ manager = new CarTrustAgentEnrollmentManager(this, binder);
break;
case CAR_MEDIA_SERVICE:
- manager = new CarMediaManager(binder);
+ manager = new CarMediaManager(this, binder);
break;
case CAR_BUGREPORT_SERVICE:
- manager = new CarBugreportManager(binder, mContext);
+ manager = new CarBugreportManager(this, binder);
break;
case CAR_USER_SERVICE:
- manager = new CarUserManager(binder);
+ manager = new CarUserManager(this, binder);
default:
break;
}
@@ -1297,15 +1358,6 @@
}
}
- private ICar getICarOrThrow() throws IllegalStateException {
- synchronized (mLock) {
- if (mService == null) {
- throw new IllegalStateException("not connected");
- }
- return mService;
- }
- }
-
private void tearDownCarManagersLocked() {
// All disconnected handling should be only doing its internal cleanup.
for (CarManagerBase manager: mServiceMap.values()) {
diff --git a/car-lib/src/android/car/CarAppFocusManager.java b/car-lib/src/android/car/CarAppFocusManager.java
index ff0c25d..b8936af 100644
--- a/car-lib/src/android/car/CarAppFocusManager.java
+++ b/car-lib/src/android/car/CarAppFocusManager.java
@@ -17,7 +17,6 @@
package android.car;
import android.annotation.IntDef;
-import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
@@ -35,7 +34,7 @@
* should run in the system, and other app setting the flag for the matching app should
* lead into other app to stop.
*/
-public final class CarAppFocusManager implements CarManagerBase {
+public final class CarAppFocusManager extends CarManagerBase {
/**
* Listener to get notification for app getting information on application type status changes.
*/
@@ -114,7 +113,6 @@
public @interface AppFocusRequestResult {}
private final IAppFocus mService;
- private final Handler mHandler;
private final Map<OnAppFocusChangedListener, IAppFocusListenerImpl> mChangeBinders =
new HashMap<>();
private final Map<OnAppFocusOwnershipCallback, IAppFocusOwnershipCallbackImpl>
@@ -123,9 +121,9 @@
/**
* @hide
*/
- CarAppFocusManager(IBinder service, Handler handler) {
+ CarAppFocusManager(Car car, IBinder service) {
+ super(car);
mService = IAppFocus.Stub.asInterface(service);
- mHandler = handler;
}
/**
@@ -149,7 +147,7 @@
try {
mService.registerFocusListener(binder, appType);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -169,7 +167,8 @@
try {
mService.unregisterFocusListener(binder, appType);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
+ // continue for local clean-up
}
synchronized (this) {
binder.removeAppType(appType);
@@ -197,7 +196,7 @@
mService.unregisterFocusListener(binder, appType);
}
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -209,7 +208,7 @@
try {
return mService.getActiveAppTypes();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, new int[0]);
}
}
@@ -229,7 +228,7 @@
try {
return mService.isOwningFocus(binder, appType);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -261,7 +260,7 @@
try {
return mService.requestAppFocus(binder, appType);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, APP_FOCUS_REQUEST_FAILED);
}
}
@@ -286,7 +285,8 @@
try {
mService.abandonAppFocus(binder, appType);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
+ // continue for local clean-up
}
synchronized (this) {
binder.removeAppType(appType);
@@ -314,7 +314,7 @@
mService.abandonAppFocus(binder, appType);
}
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -359,11 +359,8 @@
if (manager == null || listener == null) {
return;
}
- manager.mHandler.post(new Runnable() {
- @Override
- public void run() {
- listener.onAppFocusChanged(appType, active);
- }
+ manager.getEventHandler().post(() -> {
+ listener.onAppFocusChanged(appType, active);
});
}
}
@@ -403,11 +400,8 @@
if (manager == null || callback == null) {
return;
}
- manager.mHandler.post(new Runnable() {
- @Override
- public void run() {
- callback.onAppFocusOwnershipLost(appType);
- }
+ manager.getEventHandler().post(() -> {
+ callback.onAppFocusOwnershipLost(appType);
});
}
@@ -418,11 +412,8 @@
if (manager == null || callback == null) {
return;
}
- manager.mHandler.post(new Runnable() {
- @Override
- public void run() {
- callback.onAppFocusOwnershipGranted(appType);
- }
+ manager.getEventHandler().post(() -> {
+ callback.onAppFocusOwnershipGranted(appType);
});
}
}
diff --git a/car-lib/src/android/car/CarBluetoothManager.java b/car-lib/src/android/car/CarBluetoothManager.java
index c85cec7..c8e46ca 100644
--- a/car-lib/src/android/car/CarBluetoothManager.java
+++ b/car-lib/src/android/car/CarBluetoothManager.java
@@ -17,7 +17,6 @@
import android.Manifest;
import android.annotation.RequiresPermission;
-import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
@@ -26,9 +25,8 @@
*
* @hide
*/
-public final class CarBluetoothManager implements CarManagerBase {
+public final class CarBluetoothManager extends CarManagerBase {
private static final String TAG = "CarBluetoothManager";
- private final Context mContext;
private final ICarBluetooth mService;
/**
@@ -50,7 +48,7 @@
try {
mService.connectDevices();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -59,8 +57,8 @@
*
* @hide
*/
- public CarBluetoothManager(IBinder service, Context context) {
- mContext = context;
+ public CarBluetoothManager(Car car, IBinder service) {
+ super(car);
mService = ICarBluetooth.Stub.asInterface(service);
}
diff --git a/car-lib/src/android/car/CarBugreportManager.java b/car-lib/src/android/car/CarBugreportManager.java
index f5d3b1d..99f2c7c 100644
--- a/car-lib/src/android/car/CarBugreportManager.java
+++ b/car-lib/src/android/car/CarBugreportManager.java
@@ -20,7 +20,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
-import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -39,10 +38,9 @@
*
* @hide
*/
-public final class CarBugreportManager implements CarManagerBase {
+public final class CarBugreportManager extends CarManagerBase {
private final ICarBugreportService mService;
- private Handler mHandler;
/**
* Callback from carbugreport manager. Callback methods are always called on the main thread.
@@ -153,9 +151,9 @@
*
* Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead.
*/
- public CarBugreportManager(IBinder service, Context context) {
+ public CarBugreportManager(Car car, IBinder service) {
+ super(car);
mService = ICarBugreportService.Stub.asInterface(service);
- mHandler = new Handler(context.getMainLooper());
}
/**
@@ -185,10 +183,10 @@
Preconditions.checkNotNull(callback);
try {
CarBugreportManagerCallbackWrapper wrapper =
- new CarBugreportManagerCallbackWrapper(callback, mHandler);
+ new CarBugreportManagerCallbackWrapper(callback, getEventHandler());
mService.requestBugreport(output, extraOutput, wrapper);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
} finally {
IoUtils.closeQuietly(output);
IoUtils.closeQuietly(extraOutput);
diff --git a/car-lib/src/android/car/CarInfoManager.java b/car-lib/src/android/car/CarInfoManager.java
index 6a34471..c78523b 100644
--- a/car-lib/src/android/car/CarInfoManager.java
+++ b/car-lib/src/android/car/CarInfoManager.java
@@ -29,7 +29,7 @@
* Utility to retrieve various static information from car. Each data are grouped as {@link Bundle}
* and relevant data can be checked from {@link Bundle} using pre-specified keys.
*/
-public final class CarInfoManager implements CarManagerBase{
+public final class CarInfoManager extends CarManagerBase {
private final CarPropertyManager mCarPropertyMgr;
/**
@@ -261,15 +261,14 @@
}
/** @hide */
- public CarInfoManager(IBinder service) {
+ public CarInfoManager(Car car, IBinder service) {
+ super(car);
ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service);
- mCarPropertyMgr = new CarPropertyManager(mCarPropertyService, null);
+ mCarPropertyMgr = new CarPropertyManager(car, mCarPropertyService);
}
/** @hide */
public void onCarDisconnected() {
mCarPropertyMgr.onCarDisconnected();
}
-
-
}
diff --git a/car-lib/src/android/car/CarManagerBase.java b/car-lib/src/android/car/CarManagerBase.java
index 737f356..8d30fdf 100644
--- a/car-lib/src/android/car/CarManagerBase.java
+++ b/car-lib/src/android/car/CarManagerBase.java
@@ -16,10 +16,44 @@
package android.car;
+import android.content.Context;
+import android.os.Handler;
+import android.os.RemoteException;
+
/**
- * Common interface for Car*Manager
+ * Common base class for Car*Manager
* @hide
*/
-public interface CarManagerBase {
- void onCarDisconnected();
+public abstract class CarManagerBase {
+
+ protected final Car mCar;
+
+ public CarManagerBase(Car car) {
+ mCar = car;
+ }
+
+ protected Context getContext() {
+ return mCar.getContext();
+ }
+
+ protected Handler getEventHandler() {
+ return mCar.getEventHandler();
+ }
+
+ protected <T> T handleRemoteExceptionFromCarService(RemoteException e, T returnValue) {
+ return mCar.handleRemoteExceptionFromCarService(e, returnValue);
+ }
+
+ protected void handleRemoteExceptionFromCarService(RemoteException e) {
+ mCar.handleRemoteExceptionFromCarService(e);
+ }
+
+ /**
+ * Handle disconnection of car service (=crash). As car service has crashed already, this call
+ * should only clean up any listeners / callbacks passed from client. Clearing object passed
+ * to car service is not necessary as car service has crashed. Note that Car*Manager will not
+ * work any more as all binders are invalid. Client should re-create all Car*Managers when
+ * car service is restarted.
+ */
+ protected abstract void onCarDisconnected();
}
diff --git a/car-lib/src/android/car/CarOccupantZoneManager.java b/car-lib/src/android/car/CarOccupantZoneManager.java
index 32cfea0..5865991 100644
--- a/car-lib/src/android/car/CarOccupantZoneManager.java
+++ b/car-lib/src/android/car/CarOccupantZoneManager.java
@@ -19,7 +19,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.content.Context;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.IBinder;
@@ -28,6 +27,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import android.view.Display;
@@ -40,13 +40,14 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* API to get information on displays and users in the car.
*/
-public class CarOccupantZoneManager implements CarManagerBase {
+public class CarOccupantZoneManager extends CarManagerBase {
private static final String TAG = CarOccupantZoneManager.class.getSimpleName();
@@ -261,11 +262,12 @@
/** @hide */
@VisibleForTesting
- public CarOccupantZoneManager(IBinder service, Context context, Handler handler) {
+ public CarOccupantZoneManager(Car car, IBinder service) {
+ super(car);
mService = ICarOccupantZone.Stub.asInterface(service);
mBinderCallback = new ICarOccupantZoneCallbackImpl(this);
- mDisplayManager = context.getSystemService(DisplayManager.class);
- mEventHandler = new EventHandler(handler.getLooper());
+ mDisplayManager = getContext().getSystemService(DisplayManager.class);
+ mEventHandler = new EventHandler(getEventHandler().getLooper());
}
/**
@@ -277,7 +279,7 @@
try {
return Arrays.asList(mService.getAllOccupantZones());
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
@@ -303,7 +305,7 @@
}
return displays;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
@@ -326,7 +328,7 @@
}
return mDisplayManager.getDisplay(displayId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -340,7 +342,7 @@
try {
return mService.getDisplayType(display.getDisplayId());
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, DISPLAY_TYPE_UNKNOWN);
}
}
@@ -353,7 +355,7 @@
try {
return mService.getUserForOccupant(occupantZone.zoneId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, UserHandle.USER_NULL);
}
}
@@ -380,7 +382,7 @@
try {
mService.registerCallback(mBinderCallback);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
diff --git a/car-lib/src/android/car/CarProjectionManager.java b/car-lib/src/android/car/CarProjectionManager.java
index 4c177f7..bc4107f 100644
--- a/car-lib/src/android/car/CarProjectionManager.java
+++ b/car-lib/src/android/car/CarProjectionManager.java
@@ -69,7 +69,7 @@
* @hide
*/
@SystemApi
-public final class CarProjectionManager implements CarManagerBase {
+public final class CarProjectionManager extends CarManagerBase {
private static final String TAG = CarProjectionManager.class.getSimpleName();
private final Binder mToken = new Binder();
@@ -194,7 +194,6 @@
public static final int PROJECTION_AP_FAILED = 2;
private final ICarProjection mService;
- private final Handler mHandler;
private final Executor mHandlerExecutor;
@GuardedBy("mLock")
@@ -241,9 +240,10 @@
/**
* @hide
*/
- public CarProjectionManager(IBinder service, Handler handler) {
+ public CarProjectionManager(Car car, IBinder service) {
+ super(car);
mService = ICarProjection.Stub.asInterface(service);
- mHandler = handler;
+ Handler handler = getEventHandler();
mHandlerExecutor = handler::post;
}
@@ -448,7 +448,8 @@
mService.unregisterKeyEventHandler(mBinderHandler);
}
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
+ return;
}
mHandledEvents = events;
@@ -466,7 +467,7 @@
try {
mService.registerProjectionRunner(serviceIntent);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
@@ -483,7 +484,7 @@
try {
mService.unregisterProjectionRunner(serviceIntent);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
@@ -507,14 +508,14 @@
public void startProjectionAccessPoint(@NonNull ProjectionAccessPointCallback callback) {
Preconditions.checkNotNull(callback, "callback cannot be null");
synchronized (mLock) {
- Looper looper = mHandler.getLooper();
+ Looper looper = getEventHandler().getLooper();
ProjectionAccessPointCallbackProxy proxy =
new ProjectionAccessPointCallbackProxy(this, looper, callback);
try {
mService.startProjectionAccessPoint(proxy.getMessenger(), mAccessPointProxyToken);
mProjectionAccessPointCallbackProxy = proxy;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
@@ -535,7 +536,7 @@
}
return channelList;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
@@ -556,7 +557,7 @@
try {
mService.stopProjectionAccessPoint(mAccessPointProxyToken);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -575,7 +576,7 @@
try {
return mService.requestBluetoothProfileInhibit(device, profile, mToken);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -593,7 +594,7 @@
try {
return mService.releaseBluetoothProfileInhibit(device, profile, mToken);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -611,7 +612,7 @@
try {
mService.updateProjectionStatus(status, mToken);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -634,12 +635,12 @@
try {
mService.registerProjectionStatusListener(mCarProjectionStatusListener);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
} else {
// Already subscribed to Car Service, immediately notify listener with the current
// projection status in the event handler thread.
- mHandler.post(() ->
+ getEventHandler().post(() ->
listener.onProjectionStatusChanged(
mCarProjectionStatusListener.mCurrentState,
mCarProjectionStatusListener.mCurrentPackageName,
@@ -671,7 +672,7 @@
mService.unregisterProjectionStatusListener(mCarProjectionStatusListener);
mCarProjectionStatusListener = null;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -695,7 +696,7 @@
try {
return mService.getProjectionOptions();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Bundle.EMPTY);
}
}
@@ -838,7 +839,7 @@
List<ProjectionStatus> details) {
CarProjectionManager mgr = mManagerRef.get();
if (mgr != null) {
- mgr.mHandler.post(() -> {
+ mgr.getEventHandler().post(() -> {
mCurrentState = projectionState;
mCurrentPackageName = packageName;
mDetails = Collections.unmodifiableList(details);
diff --git a/car-lib/src/android/car/CarUserManager.java b/car-lib/src/android/car/CarUserManager.java
index 7453cad..6ea62af 100644
--- a/car-lib/src/android/car/CarUserManager.java
+++ b/car-lib/src/android/car/CarUserManager.java
@@ -27,6 +27,7 @@
import com.android.internal.annotations.VisibleForTesting;
+import java.util.Collections;
import java.util.List;
/**
@@ -35,14 +36,15 @@
* @hide
*/
@SystemApi
-public final class CarUserManager implements CarManagerBase {
+public final class CarUserManager extends CarManagerBase {
private static final String TAG = CarUserManager.class.getSimpleName();
private final ICarUserService mService;
/** @hide */
@VisibleForTesting
- public CarUserManager(@NonNull IBinder service) {
+ public CarUserManager(Car car, @NonNull IBinder service) {
+ super(car);
mService = ICarUserService.Stub.asInterface(service);
}
@@ -63,7 +65,7 @@
try {
return mService.createDriver(name, admin);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -84,7 +86,7 @@
try {
return mService.createPassenger(name, driverId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -102,7 +104,7 @@
try {
return mService.switchDriver(driverId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -120,7 +122,7 @@
try {
return mService.getAllDrivers();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
@@ -139,7 +141,7 @@
try {
return mService.getPassengers(driverId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
@@ -159,7 +161,7 @@
try {
return mService.startPassenger(passengerId, zoneId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -177,7 +179,7 @@
try {
return mService.stopPassenger(passengerId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
diff --git a/car-lib/src/android/car/cluster/CarInstrumentClusterManager.java b/car-lib/src/android/car/cluster/CarInstrumentClusterManager.java
index 54d10e2..2b633a0 100644
--- a/car-lib/src/android/car/cluster/CarInstrumentClusterManager.java
+++ b/car-lib/src/android/car/cluster/CarInstrumentClusterManager.java
@@ -17,10 +17,10 @@
package android.car.cluster;
import android.annotation.SystemApi;
+import android.car.Car;
import android.car.CarManagerBase;
import android.content.Intent;
import android.os.Bundle;
-import android.os.Handler;
import android.os.IBinder;
/**
@@ -35,7 +35,7 @@
*/
@Deprecated
@SystemApi
-public class CarInstrumentClusterManager implements CarManagerBase {
+public class CarInstrumentClusterManager extends CarManagerBase {
/**
* @deprecated use {@link android.car.Car#CATEGORY_NAVIGATION} instead
*
@@ -101,7 +101,8 @@
}
/** @hide */
- public CarInstrumentClusterManager(IBinder service, Handler handler) {
+ public CarInstrumentClusterManager(Car car, IBinder service) {
+ super(car);
// No-op
}
diff --git a/car-lib/src/android/car/content/pm/CarAppBlockingPolicyService.java b/car-lib/src/android/car/content/pm/CarAppBlockingPolicyService.java
index 5b0a6bd..f95063a 100644
--- a/car-lib/src/android/car/content/pm/CarAppBlockingPolicyService.java
+++ b/car-lib/src/android/car/content/pm/CarAppBlockingPolicyService.java
@@ -17,6 +17,7 @@
import android.annotation.SystemApi;
import android.app.Service;
+import android.car.Car;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
@@ -76,7 +77,7 @@
try {
setter.setAppBlockingPolicy(policy);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ Car.handleRemoteExceptionFromCarService(CarAppBlockingPolicyService.this, e);
}
}
}
diff --git a/car-lib/src/android/car/content/pm/CarPackageManager.java b/car-lib/src/android/car/content/pm/CarPackageManager.java
index d23633d..7498c65 100644
--- a/car-lib/src/android/car/content/pm/CarPackageManager.java
+++ b/car-lib/src/android/car/content/pm/CarPackageManager.java
@@ -19,9 +19,9 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.car.Car;
import android.car.CarManagerBase;
import android.content.ComponentName;
-import android.content.Context;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
@@ -32,7 +32,7 @@
/**
* Provides car specific API related with package management.
*/
-public final class CarPackageManager implements CarManagerBase {
+public final class CarPackageManager extends CarManagerBase {
private static final String TAG = "CarPackageManager";
/**
@@ -70,12 +70,11 @@
public @interface SetPolicyFlags {}
private final ICarPackageManager mService;
- private final Context mContext;
/** @hide */
- public CarPackageManager(IBinder service, Context context) {
+ public CarPackageManager(Car car, IBinder service) {
+ super(car);
mService = ICarPackageManager.Stub.asInterface(service);
- mContext = context;
}
/** @hide */
@@ -115,7 +114,7 @@
try {
mService.setAppBlockingPolicy(packageName, policy, flags);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -128,7 +127,7 @@
try {
mService.restartTask(taskId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -151,7 +150,7 @@
try {
return mService.isActivityBackedBySafeActivity(activityName);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -165,7 +164,7 @@
try {
mService.setEnableActivityBlocking(enable);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -181,7 +180,7 @@
try {
return mService.isActivityDistractionOptimized(packageName, className);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -197,7 +196,7 @@
try {
return mService.isServiceDistractionOptimized(packageName, className);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
}
diff --git a/car-lib/src/android/car/diagnostic/CarDiagnosticManager.java b/car-lib/src/android/car/diagnostic/CarDiagnosticManager.java
index 1559dd4..c9c8b6f 100644
--- a/car-lib/src/android/car/diagnostic/CarDiagnosticManager.java
+++ b/car-lib/src/android/car/diagnostic/CarDiagnosticManager.java
@@ -23,8 +23,6 @@
import android.car.CarLibLog;
import android.car.CarManagerBase;
import android.car.diagnostic.ICarDiagnosticEventListener.Stub;
-import android.content.Context;
-import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -47,7 +45,7 @@
* @hide
*/
@SystemApi
-public final class CarDiagnosticManager implements CarManagerBase {
+public final class CarDiagnosticManager extends CarManagerBase {
public static final int FRAME_TYPE_LIVE = 0;
public static final int FRAME_TYPE_FREEZE = 1;
@@ -70,15 +68,16 @@
/** Handles call back into clients. */
private final SingleMessageHandler<CarDiagnosticEvent> mHandlerCallback;
- private CarDiagnosticEventListenerToService mListenerToService;
+ private final CarDiagnosticEventListenerToService mListenerToService;
private final CarPermission mVendorExtensionPermission;
/** @hide */
- public CarDiagnosticManager(IBinder service, Context context, Handler handler) {
+ public CarDiagnosticManager(Car car, IBinder service) {
+ super(car);
mService = ICarDiagnostic.Stub.asInterface(service);
- mHandlerCallback = new SingleMessageHandler<CarDiagnosticEvent>(handler.getLooper(),
- MSG_DIAGNOSTIC_EVENTS) {
+ mHandlerCallback = new SingleMessageHandler<CarDiagnosticEvent>(
+ getEventHandler().getLooper(), MSG_DIAGNOSTIC_EVENTS) {
@Override
protected void handleEvent(CarDiagnosticEvent event) {
CarDiagnosticListeners listeners;
@@ -90,7 +89,9 @@
}
}
};
- mVendorExtensionPermission = new CarPermission(context, Car.PERMISSION_VENDOR_EXTENSION);
+ mVendorExtensionPermission = new CarPermission(getContext(),
+ Car.PERMISSION_VENDOR_EXTENSION);
+ mListenerToService = new CarDiagnosticEventListenerToService(this);
}
@Override
@@ -98,7 +99,6 @@
public void onCarDisconnected() {
synchronized(mActiveListeners) {
mActiveListeners.clear();
- mListenerToService = null;
}
}
@@ -137,9 +137,6 @@
OnDiagnosticEventListener listener, @FrameType int frameType, int rate) {
assertFrameType(frameType);
synchronized(mActiveListeners) {
- if (null == mListenerToService) {
- mListenerToService = new CarDiagnosticEventListenerToService(this);
- }
boolean needsServerUpdate = false;
CarDiagnosticListeners listeners = mActiveListeners.get(frameType);
if (listeners == null) {
@@ -184,7 +181,8 @@
mService.unregisterDiagnosticListener(frameType,
mListenerToService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
+ // continue for local clean-up
}
mActiveListeners.remove(frameType);
} else if (needsServerUpdate) {
@@ -197,7 +195,7 @@
try {
return mService.registerOrUpdateDiagnosticListener(frameType, rate, mListenerToService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -212,7 +210,7 @@
try {
return mService.getLatestLiveFrame();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -229,7 +227,7 @@
try {
return mService.getFreezeFrameTimestamps();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, new long[0]);
}
}
@@ -246,7 +244,7 @@
try {
return mService.getFreezeFrame(timestamp);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -264,7 +262,7 @@
try {
return mService.clearFreezeFrames(timestamps);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -276,7 +274,7 @@
try {
return mService.isLiveFrameSupported();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -288,7 +286,7 @@
try {
return mService.isFreezeFrameNotificationSupported();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -300,7 +298,7 @@
try {
return mService.isGetFreezeFrameSupported();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -318,7 +316,7 @@
try {
return mService.isClearFreezeFramesSupported();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -336,7 +334,7 @@
try {
return mService.isSelectiveClearFreezeFramesSupported();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
diff --git a/car-lib/src/android/car/drivingstate/CarDrivingStateManager.java b/car-lib/src/android/car/drivingstate/CarDrivingStateManager.java
index 9b0626f..4053c5c 100644
--- a/car-lib/src/android/car/drivingstate/CarDrivingStateManager.java
+++ b/car-lib/src/android/car/drivingstate/CarDrivingStateManager.java
@@ -22,7 +22,6 @@
import android.annotation.TestApi;
import android.car.Car;
import android.car.CarManagerBase;
-import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -40,13 +39,12 @@
*/
@SystemApi
@TestApi
-public final class CarDrivingStateManager implements CarManagerBase {
+public final class CarDrivingStateManager extends CarManagerBase {
private static final String TAG = "CarDrivingStateMgr";
private static final boolean DBG = false;
private static final boolean VDBG = false;
private static final int MSG_HANDLE_DRIVING_STATE_CHANGE = 0;
- private final Context mContext;
private final ICarDrivingState mDrivingService;
private final EventCallbackHandler mEventCallbackHandler;
private CarDrivingStateEventListener mDrvStateEventListener;
@@ -54,10 +52,10 @@
/** @hide */
- public CarDrivingStateManager(IBinder service, Context context, Handler handler) {
- mContext = context;
+ public CarDrivingStateManager(Car car, IBinder service) {
+ super(car);
mDrivingService = ICarDrivingState.Stub.asInterface(service);
- mEventCallbackHandler = new EventCallbackHandler(this, handler.getLooper());
+ mEventCallbackHandler = new EventCallbackHandler(this, getEventHandler().getLooper());
}
/** @hide */
@@ -111,7 +109,7 @@
// register to the Service for getting notified
mDrivingService.registerDrivingStateChangeListener(mListenerToService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -134,7 +132,7 @@
mDrvStateEventListener = null;
mListenerToService = null;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -151,7 +149,7 @@
try {
return mDrivingService.getCurrentDrivingState();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -172,7 +170,7 @@
try {
mDrivingService.injectDrivingState(event);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
diff --git a/car-lib/src/android/car/drivingstate/CarUxRestrictionsManager.java b/car-lib/src/android/car/drivingstate/CarUxRestrictionsManager.java
index 9a3d5cf..be194b8 100644
--- a/car-lib/src/android/car/drivingstate/CarUxRestrictionsManager.java
+++ b/car-lib/src/android/car/drivingstate/CarUxRestrictionsManager.java
@@ -22,7 +22,6 @@
import android.annotation.RequiresPermission;
import android.car.Car;
import android.car.CarManagerBase;
-import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -43,7 +42,7 @@
* API to register and get the User Experience restrictions imposed based on the car's driving
* state.
*/
-public final class CarUxRestrictionsManager implements CarManagerBase {
+public final class CarUxRestrictionsManager extends CarManagerBase {
private static final String TAG = "CarUxRManager";
private static final boolean DBG = false;
private static final boolean VDBG = false;
@@ -80,7 +79,6 @@
@Retention(RetentionPolicy.SOURCE)
public @interface UxRestrictionMode {}
- private final Context mContext;
private int mDisplayId = Display.INVALID_DISPLAY;
private final ICarUxRestrictionsManager mUxRService;
private final EventCallbackHandler mEventCallbackHandler;
@@ -89,10 +87,11 @@
private CarUxRestrictionsChangeListenerToService mListenerToService;
/** @hide */
- public CarUxRestrictionsManager(IBinder service, Context context, Handler handler) {
- mContext = context;
+ public CarUxRestrictionsManager(Car car, IBinder service) {
+ super(car);
mUxRService = ICarUxRestrictionsManager.Stub.asInterface(service);
- mEventCallbackHandler = new EventCallbackHandler(this, handler.getLooper());
+ mEventCallbackHandler = new EventCallbackHandler(this,
+ getEventHandler().getLooper());
}
/** @hide */
@@ -152,7 +151,7 @@
// register to the Service to listen for changes.
mUxRService.registerUxRestrictionsChangeListener(mListenerToService, displayId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -172,7 +171,7 @@
try {
mUxRService.unregisterUxRestrictionsChangeListener(mListenerToService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -197,7 +196,7 @@
try {
return mUxRService.saveUxRestrictionsConfigurationForNextBoot(configs);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -219,7 +218,7 @@
try {
return mUxRService.getCurrentUxRestrictions(displayId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -233,7 +232,7 @@
try {
return mUxRService.setRestrictionMode(mode);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -248,7 +247,7 @@
try {
return mUxRService.getRestrictionMode();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -288,7 +287,7 @@
try {
return mUxRService.getStagedConfigs();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -304,7 +303,7 @@
try {
return mUxRService.getConfigs();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -399,7 +398,7 @@
return mDisplayId;
}
- mDisplayId = mContext.getDisplayId();
+ mDisplayId = getContext().getDisplayId();
Log.i(TAG, "Context returns display ID " + mDisplayId);
if (mDisplayId == Display.INVALID_DISPLAY) {
diff --git a/car-lib/src/android/car/hardware/CarSensorManager.java b/car-lib/src/android/car/hardware/CarSensorManager.java
index d61cb2e..082c8eb 100644
--- a/car-lib/src/android/car/hardware/CarSensorManager.java
+++ b/car-lib/src/android/car/hardware/CarSensorManager.java
@@ -26,9 +26,7 @@
import android.car.hardware.property.CarPropertyManager;
import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
import android.car.hardware.property.ICarProperty;
-import android.content.Context;
import android.os.Bundle;
-import android.os.Handler;
import android.os.IBinder;
import android.util.ArraySet;
import android.util.Log;
@@ -46,7 +44,7 @@
* API for monitoring car sensor data.
*/
@Deprecated
-public final class CarSensorManager implements CarManagerBase {
+public final class CarSensorManager extends CarManagerBase {
private static final String TAG = "CarSensorManager";
private final CarPropertyManager mCarPropertyMgr;
/** @hide */
@@ -304,9 +302,10 @@
}
/** @hide */
- public CarSensorManager(IBinder service, Context context, Handler handler) {
+ public CarSensorManager(Car car, IBinder service) {
+ super(car);
ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service);
- mCarPropertyMgr = new CarPropertyManager(mCarPropertyService, handler);
+ mCarPropertyMgr = new CarPropertyManager(car, mCarPropertyService);
}
/** @hide */
diff --git a/car-lib/src/android/car/hardware/CarVendorExtensionManager.java b/car-lib/src/android/car/hardware/CarVendorExtensionManager.java
index e7df3b0..b796156 100644
--- a/car-lib/src/android/car/hardware/CarVendorExtensionManager.java
+++ b/car-lib/src/android/car/hardware/CarVendorExtensionManager.java
@@ -22,7 +22,6 @@
import android.car.hardware.property.CarPropertyManager;
import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
import android.car.hardware.property.ICarProperty;
-import android.os.Handler;
import android.os.IBinder;
import android.util.ArraySet;
@@ -44,7 +43,7 @@
*/
@Deprecated
@SystemApi
-public final class CarVendorExtensionManager implements CarManagerBase {
+public final class CarVendorExtensionManager extends CarManagerBase {
private final static boolean DBG = false;
private final static String TAG = CarVendorExtensionManager.class.getSimpleName();
@@ -84,9 +83,10 @@
* <p>Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead.
* @hide
*/
- public CarVendorExtensionManager(IBinder service, Handler handler) {
+ public CarVendorExtensionManager(Car car, IBinder service) {
+ super(car);
ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service);
- mPropertyManager = new CarPropertyManager(mCarPropertyService, handler);
+ mPropertyManager = new CarPropertyManager(car, mCarPropertyService);
}
/**
@@ -206,6 +206,9 @@
/** @hide */
@Override
public void onCarDisconnected() {
+ synchronized (mLock) {
+ mCallbacks.clear();
+ }
mPropertyManager.onCarDisconnected();
}
private static class CarPropertyEventListenerToBase implements CarPropertyEventCallback {
diff --git a/car-lib/src/android/car/hardware/cabin/CarCabinManager.java b/car-lib/src/android/car/hardware/cabin/CarCabinManager.java
index 1c41a2b..7318176 100644
--- a/car-lib/src/android/car/hardware/cabin/CarCabinManager.java
+++ b/car-lib/src/android/car/hardware/cabin/CarCabinManager.java
@@ -25,8 +25,6 @@
import android.car.hardware.property.CarPropertyManager;
import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
import android.car.hardware.property.ICarProperty;
-import android.content.Context;
-import android.os.Handler;
import android.os.IBinder;
import android.util.ArraySet;
@@ -58,7 +56,7 @@
*/
@Deprecated
@SystemApi
-public final class CarCabinManager implements CarManagerBase {
+public final class CarCabinManager extends CarManagerBase {
private final static boolean DBG = false;
private final static String TAG = "CarCabinManager";
private final CarPropertyManager mCarPropertyMgr;
@@ -470,9 +468,10 @@
* @param handler
* @hide
*/
- public CarCabinManager(IBinder service, Context context, Handler handler) {
+ public CarCabinManager(Car car, IBinder service) {
+ super(car);
ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service);
- mCarPropertyMgr = new CarPropertyManager(mCarPropertyService, handler);
+ mCarPropertyMgr = new CarPropertyManager(car, mCarPropertyService);
}
/**
@@ -594,6 +593,10 @@
/** @hide */
@Override
public void onCarDisconnected() {
+ // TODO(b/142730969) Fix synchronization to use separate mLock
+ synchronized (this) {
+ mCallbacks.clear();
+ }
mCarPropertyMgr.onCarDisconnected();
}
}
diff --git a/car-lib/src/android/car/hardware/hvac/CarHvacManager.java b/car-lib/src/android/car/hardware/hvac/CarHvacManager.java
index 3b7c098..f6a2d53 100644
--- a/car-lib/src/android/car/hardware/hvac/CarHvacManager.java
+++ b/car-lib/src/android/car/hardware/hvac/CarHvacManager.java
@@ -25,8 +25,6 @@
import android.car.hardware.property.CarPropertyManager;
import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
import android.car.hardware.property.ICarProperty;
-import android.content.Context;
-import android.os.Handler;
import android.os.IBinder;
import android.util.ArraySet;
import android.util.Log;
@@ -46,7 +44,7 @@
*/
@Deprecated
@SystemApi
-public final class CarHvacManager implements CarManagerBase {
+public final class CarHvacManager extends CarManagerBase {
private final static boolean DBG = false;
private final static String TAG = "CarHvacManager";
private final CarPropertyManager mCarPropertyMgr;
@@ -304,14 +302,15 @@
*
* Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead.
* @param service
- * @param context
- * @param handler
+ *
* @hide
*/
- public CarHvacManager(IBinder service, Context context, Handler handler) {
+ public CarHvacManager(Car car, IBinder service) {
+ super(car);
ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service);
- mCarPropertyMgr = new CarPropertyManager(mCarPropertyService, handler);
+ mCarPropertyMgr = new CarPropertyManager(car, mCarPropertyService);
}
+
/**
* Implement wrappers for contained CarPropertyManager object
* @param callback
@@ -435,6 +434,10 @@
/** @hide */
public void onCarDisconnected() {
+ // TODO(b/142730482) Fix synchronization to use separate mLock
+ synchronized (this) {
+ mCallbacks.clear();
+ }
mCarPropertyMgr.onCarDisconnected();
}
}
diff --git a/car-lib/src/android/car/hardware/power/CarPowerManager.java b/car-lib/src/android/car/hardware/power/CarPowerManager.java
index 3d9a23a..4b0e8cf 100644
--- a/car-lib/src/android/car/hardware/power/CarPowerManager.java
+++ b/car-lib/src/android/car/hardware/power/CarPowerManager.java
@@ -19,8 +19,6 @@
import android.annotation.SystemApi;
import android.car.Car;
import android.car.CarManagerBase;
-import android.content.Context;
-import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -35,15 +33,18 @@
* @hide
*/
@SystemApi
-public class CarPowerManager implements CarManagerBase {
+public class CarPowerManager extends CarManagerBase {
private final static boolean DBG = false;
private final static String TAG = "CarPowerManager";
private final Object mLock = new Object();
private final ICarPower mService;
+ @GuardedBy("mLock")
private CarPowerStateListener mListener;
+ @GuardedBy("mLock")
private CarPowerStateListenerWithCompletion mListenerWithCompletion;
+ @GuardedBy("mLock")
private CompletableFuture<Void> mFuture;
@GuardedBy("mLock")
private ICarPowerStateListener mListenerToService;
@@ -131,7 +132,8 @@
* @param handler
* @hide
*/
- public CarPowerManager(IBinder service, Context context, Handler handler) {
+ public CarPowerManager(Car car, IBinder service) {
+ super(car);
mService = ICarPower.Stub.asInterface(service);
}
@@ -143,7 +145,7 @@
try {
mService.requestShutdownOnNextSuspend();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -155,7 +157,7 @@
try {
mService.scheduleNextWakeupTime(seconds);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -209,13 +211,23 @@
@Override
public void onStateChanged(int state) throws RemoteException {
if (useCompletion) {
- // Update CompletableFuture. This will recreate it or just clean it up.
- updateFuture(state);
+ CarPowerStateListenerWithCompletion listenerWithCompletion;
+ CompletableFuture<Void> future;
+ synchronized (mLock) {
+ // Update CompletableFuture. This will recreate it or just clean it up.
+ updateFutureLocked(state);
+ listenerWithCompletion = mListenerWithCompletion;
+ future = mFuture;
+ }
// Notify user that the state has changed and supply a future
- mListenerWithCompletion.onStateChanged(state, mFuture);
+ listenerWithCompletion.onStateChanged(state, future);
} else {
+ CarPowerStateListener listener;
+ synchronized (mLock) {
+ listener = mListener;
+ }
// Notify the user without supplying a future
- mListener.onStateChanged(state);
+ listener.onStateChanged(state);
}
}
};
@@ -227,7 +239,7 @@
}
mListenerToService = listenerToService;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
@@ -243,7 +255,7 @@
mListenerToService = null;
mListener = null;
mListenerWithCompletion = null;
- cleanupFuture();
+ cleanupFutureLocked();
}
if (listenerToService == null) {
@@ -254,12 +266,12 @@
try {
mService.unregisterListener(listenerToService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
- private void updateFuture(int state) {
- cleanupFuture();
+ private void updateFutureLocked(int state) {
+ cleanupFutureLocked();
if (state == CarPowerStateListener.SHUTDOWN_PREPARE) {
// Create a CompletableFuture and pass it to the listener.
// When the listener completes the future, tell
@@ -269,16 +281,20 @@
if (exception != null && !(exception instanceof CancellationException)) {
Log.e(TAG, "Exception occurred while waiting for future", exception);
}
+ ICarPowerStateListener listenerToService;
+ synchronized (mLock) {
+ listenerToService = mListenerToService;
+ }
try {
- mService.finished(mListenerToService);
+ mService.finished(listenerToService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
});
}
}
- private void cleanupFuture() {
+ private void cleanupFutureLocked() {
if (mFuture != null) {
if (!mFuture.isDone()) {
mFuture.cancel(false);
@@ -290,13 +306,9 @@
/** @hide */
@Override
public void onCarDisconnected() {
- ICarPowerStateListener listenerToService;
synchronized (mLock) {
- listenerToService = mListenerToService;
- }
-
- if (listenerToService != null) {
- clearListener();
+ mListener = null;
+ mListenerWithCompletion = null;
}
}
}
diff --git a/car-lib/src/android/car/hardware/property/CarPropertyManager.java b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
index 3f7da1d..e3651da 100644
--- a/car-lib/src/android/car/hardware/property/CarPropertyManager.java
+++ b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
@@ -21,6 +21,7 @@
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.car.Car;
import android.car.CarManagerBase;
import android.car.hardware.CarPropertyConfig;
import android.car.hardware.CarPropertyValue;
@@ -44,7 +45,7 @@
* For details about the individual properties, see the descriptions in
* hardware/interfaces/automotive/vehicle/types.hal
*/
-public class CarPropertyManager implements CarManagerBase {
+public class CarPropertyManager extends CarManagerBase {
private static final boolean DBG = false;
private static final String TAG = "CarPropertyManager";
private static final int MSG_GENERIC_EVENT = 0;
@@ -93,11 +94,12 @@
* Get an instance of the CarPropertyManager.
*
* Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead.
+ * @param car Car instance
* @param service ICarProperty instance
- * @param handler The handler to deal with CarPropertyEvent.
* @hide
*/
- public CarPropertyManager(@NonNull ICarProperty service, @Nullable Handler handler) {
+ public CarPropertyManager(Car car, @NonNull ICarProperty service) {
+ super(car);
mService = service;
try {
List<CarPropertyConfig> configs = mService.getPropertyList();
@@ -108,11 +110,12 @@
Log.e(TAG, "getPropertyList exception ", e);
throw new RuntimeException(e);
}
- if (handler == null) {
+ Handler eventHandler = getEventHandler();
+ if (eventHandler == null) {
mHandler = null;
return;
}
- mHandler = new SingleMessageHandler<CarPropertyEvent>(handler.getLooper(),
+ mHandler = new SingleMessageHandler<CarPropertyEvent>(eventHandler.getLooper(),
MSG_GENERIC_EVENT) {
@Override
protected void handleEvent(CarPropertyEvent event) {
@@ -206,7 +209,7 @@
try {
mService.registerListener(propertyId, rate, mCarPropertyEventToService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
return true;
}
@@ -274,7 +277,8 @@
try {
mService.unregisterListener(propertyId, mCarPropertyEventToService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
+ // continue for local clean-up
}
mActivePropertyListener.remove(propertyId);
} else if (needsServerUpdate) {
@@ -327,7 +331,7 @@
try {
return mService.getReadPermission(propId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, "");
}
}
@@ -346,7 +350,7 @@
try {
return mService.getWritePermission(propId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, "");
}
}
@@ -363,7 +367,7 @@
return (propValue != null)
&& (propValue.getStatus() == CarPropertyValue.STATUS_AVAILABLE);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -449,7 +453,7 @@
}
return propVal;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -466,7 +470,7 @@
CarPropertyValue<E> propVal = mService.getProperty(propId, areaId);
return propVal;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -488,7 +492,7 @@
try {
mService.setProperty(new CarPropertyValue<>(propId, areaId, val));
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
diff --git a/car-lib/src/android/car/input/CarInputHandlingService.java b/car-lib/src/android/car/input/CarInputHandlingService.java
index 518cee1..0ea990f 100644
--- a/car-lib/src/android/car/input/CarInputHandlingService.java
+++ b/car-lib/src/android/car/input/CarInputHandlingService.java
@@ -19,6 +19,7 @@
import android.annotation.MainThread;
import android.annotation.SystemApi;
import android.app.Service;
+import android.car.Car;
import android.car.CarLibLog;
import android.content.Intent;
import android.os.Bundle;
@@ -101,7 +102,7 @@
try {
callbackBinder.transact(INPUT_CALLBACK_BINDER_CODE, dataIn, null, IBinder.FLAG_ONEWAY);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ Car.handleRemoteExceptionFromCarService(this, e);
}
}
diff --git a/car-lib/src/android/car/media/CarAudioManager.java b/car-lib/src/android/car/media/CarAudioManager.java
index dcd4514..2bc8fd7 100644
--- a/car-lib/src/android/car/media/CarAudioManager.java
+++ b/car-lib/src/android/car/media/CarAudioManager.java
@@ -22,10 +22,8 @@
import android.car.Car;
import android.car.CarLibLog;
import android.car.CarManagerBase;
-import android.content.Context;
import android.media.AudioAttributes;
import android.os.Bundle;
-import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -52,7 +50,7 @@
* - There is exactly one audio zone, which is the primary zone
* - Each volume group represents a controllable STREAM_TYPE, same as AudioManager
*/
-public final class CarAudioManager implements CarManagerBase {
+public final class CarAudioManager extends CarManagerBase {
/**
* Zone id of the primary audio zone.
@@ -114,7 +112,7 @@
try {
return mService.isDynamicRoutingEnabled();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -147,7 +145,7 @@
try {
mService.setGroupVolume(zoneId, groupId, index, flags);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -177,7 +175,7 @@
try {
return mService.getGroupMaxVolume(zoneId, groupId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, 0);
}
}
@@ -207,7 +205,7 @@
try {
return mService.getGroupMinVolume(zoneId, groupId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, 0);
}
}
@@ -240,7 +238,7 @@
try {
return mService.getGroupVolume(zoneId, groupId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, 0);
}
}
@@ -259,7 +257,7 @@
try {
mService.setFadeTowardFront(value);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -278,7 +276,7 @@
try {
mService.setBalanceTowardRight(value);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -300,7 +298,8 @@
try {
return mService.getExternalSources();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
+ return new String[0];
}
}
@@ -330,7 +329,7 @@
try {
return mService.createAudioPatch(sourceAddress, usage, gainInMillibels);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -350,7 +349,7 @@
try {
mService.releaseAudioPatch(patch);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -379,7 +378,7 @@
try {
return mService.getVolumeGroupCount(zoneId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, 0);
}
}
@@ -409,7 +408,7 @@
try {
return mService.getVolumeGroupIdForUsage(zoneId, usage);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, 0);
}
}
@@ -436,7 +435,7 @@
try {
return mService.getAudioZoneIds();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, new int[0]);
}
}
@@ -453,7 +452,7 @@
try {
return mService.getZoneIdForUid(uid);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, 0);
}
}
@@ -470,7 +469,7 @@
try {
return mService.setZoneIdForUid(zoneId, uid);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -486,7 +485,7 @@
try {
return mService.clearZoneIdForUid(uid);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -523,7 +522,7 @@
try {
return mService.getZoneIdForDisplayPortId(displayPortId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, 0);
}
}
@@ -541,7 +540,7 @@
try {
return mService.getUsagesForVolumeGroupId(zoneId, groupId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, new int[0]);
}
}
@@ -552,16 +551,16 @@
try {
mService.unregisterVolumeCallback(mCarVolumeCallbackImpl.asBinder());
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
/** @hide */
- public CarAudioManager(IBinder service, Context context, Handler handler) {
+ public CarAudioManager(Car car, IBinder service) {
+ super(car);
mService = ICarAudio.Stub.asInterface(service);
mCarVolumeCallbacks = new ArrayList<>();
-
try {
mService.registerVolumeCallback(mCarVolumeCallbackImpl.asBinder());
} catch (RemoteException e) {
diff --git a/car-lib/src/android/car/media/CarMediaManager.java b/car-lib/src/android/car/media/CarMediaManager.java
index 12c2dc8..8537ed6 100644
--- a/car-lib/src/android/car/media/CarMediaManager.java
+++ b/car-lib/src/android/car/media/CarMediaManager.java
@@ -29,7 +29,7 @@
* API for updating and receiving updates to the primary media source in the car.
* @hide
*/
-public final class CarMediaManager implements CarManagerBase {
+public final class CarMediaManager extends CarManagerBase {
private final ICarMedia mService;
private Map<MediaSourceChangedListener, ICarMediaSourceListener> mCallbackMap = new HashMap();
@@ -40,7 +40,8 @@
* Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead.
* @hide
*/
- public CarMediaManager(IBinder service) {
+ public CarMediaManager(Car car, IBinder service) {
+ super(car);
mService = ICarMedia.Stub.asInterface(service);
}
@@ -67,7 +68,7 @@
try {
return mService.getMediaSource();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -81,7 +82,7 @@
try {
mService.setMediaSource(componentName);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -102,7 +103,7 @@
mCallbackMap.put(callback, binderCallback);
mService.registerMediaSourceListener(binderCallback);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -117,12 +118,14 @@
ICarMediaSourceListener binderCallback = mCallbackMap.remove(callback);
mService.unregisterMediaSourceListener(binderCallback);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
/** @hide */
@Override
public synchronized void onCarDisconnected() {
+ // TODO(b/142733057) Fix synchronization to use separate mLock
+ mCallbackMap.clear();
}
}
diff --git a/car-lib/src/android/car/navigation/CarNavigationStatusManager.java b/car-lib/src/android/car/navigation/CarNavigationStatusManager.java
index a70e3c8..2aa2f10 100644
--- a/car-lib/src/android/car/navigation/CarNavigationStatusManager.java
+++ b/car-lib/src/android/car/navigation/CarNavigationStatusManager.java
@@ -24,14 +24,13 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.util.Log;
/**
* API for providing navigation status for instrument cluster.
* @hide
*/
@SystemApi
-public final class CarNavigationStatusManager implements CarManagerBase {
+public final class CarNavigationStatusManager extends CarManagerBase {
private static final String TAG = CarLibLog.TAG_NAV;
private final IInstrumentClusterNavigation mService;
@@ -40,7 +39,8 @@
* Only for CarServiceLoader
* @hide
*/
- public CarNavigationStatusManager(IBinder service) {
+ public CarNavigationStatusManager(Car car, IBinder service) {
+ super(car);
mService = IInstrumentClusterNavigation.Stub.asInterface(service);
}
@@ -67,14 +67,13 @@
try {
mService.onNavigationStateChanged(bundle);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
/** @hide */
@Override
public void onCarDisconnected() {
- Log.e(TAG, "Car service disconnected");
}
/** Returns navigation features of instrument cluster */
@@ -83,7 +82,7 @@
try {
return mService.getInstrumentClusterInfo();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
}
diff --git a/car-lib/src/android/car/settings/CarConfigurationManager.java b/car-lib/src/android/car/settings/CarConfigurationManager.java
index 34d5f4a..626ad39 100644
--- a/car-lib/src/android/car/settings/CarConfigurationManager.java
+++ b/car-lib/src/android/car/settings/CarConfigurationManager.java
@@ -16,6 +16,7 @@
package android.car.settings;
+import android.car.Car;
import android.car.CarManagerBase;
import android.os.IBinder;
import android.os.RemoteException;
@@ -23,13 +24,14 @@
/**
* Manager that exposes car configuration values that are stored on the system.
*/
-public class CarConfigurationManager implements CarManagerBase {
+public class CarConfigurationManager extends CarManagerBase {
private static final String TAG = "CarConfigurationManager";
private final ICarConfigurationManager mConfigurationService;
/** @hide */
- public CarConfigurationManager(IBinder service) {
+ public CarConfigurationManager(Car car, IBinder service) {
+ super(car);
mConfigurationService = ICarConfigurationManager.Stub.asInterface(service);
}
@@ -42,7 +44,7 @@
try {
return mConfigurationService.getSpeedBumpConfiguration();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
diff --git a/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java b/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java
index ff7b099..69c092b 100644
--- a/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java
+++ b/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java
@@ -19,7 +19,6 @@
import android.annotation.SystemApi;
import android.car.Car;
import android.car.CarManagerBase;
-import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
@@ -37,7 +36,7 @@
* @hide
*/
@SystemApi
-public final class CarStorageMonitoringManager implements CarManagerBase {
+public final class CarStorageMonitoringManager extends CarManagerBase {
private static final String TAG = CarStorageMonitoringManager.class.getSimpleName();
private static final int MSG_IO_STATS_EVENT = 0;
@@ -77,9 +76,10 @@
/**
* @hide
*/
- public CarStorageMonitoringManager(IBinder service, Handler handler) {
+ public CarStorageMonitoringManager(Car car, IBinder service) {
+ super(car);
mService = ICarStorageMonitoring.Stub.asInterface(service);
- mMessageHandler = new SingleMessageHandler<IoStats>(handler, MSG_IO_STATS_EVENT) {
+ mMessageHandler = new SingleMessageHandler<IoStats>(getEventHandler(), MSG_IO_STATS_EVENT) {
@Override
protected void handleEvent(IoStats event) {
for (IoStatsListener listener : mListeners) {
@@ -112,7 +112,7 @@
try {
return mService.getPreEolIndicatorStatus();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, PRE_EOL_INFO_UNKNOWN);
}
}
@@ -130,7 +130,7 @@
try {
return mService.getWearEstimate();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -150,7 +150,7 @@
try {
return mService.getWearEstimateHistory();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
@@ -169,7 +169,7 @@
try {
return mService.getBootIoStats();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
@@ -199,7 +199,7 @@
try {
return mService.getShutdownDiskWriteAmount();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, 0);
}
}
@@ -216,7 +216,7 @@
try {
return mService.getAggregateIoStats();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
@@ -236,7 +236,7 @@
try {
return mService.getIoStatsDeltas();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
@@ -259,7 +259,7 @@
}
mListeners.add(listener);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -277,7 +277,7 @@
mListenerToService = null;
}
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
diff --git a/car-lib/src/android/car/test/CarTestManagerBinderWrapper.java b/car-lib/src/android/car/test/CarTestManagerBinderWrapper.java
index 5e39ea3..0a167cf 100644
--- a/car-lib/src/android/car/test/CarTestManagerBinderWrapper.java
+++ b/car-lib/src/android/car/test/CarTestManagerBinderWrapper.java
@@ -15,6 +15,7 @@
*/
package android.car.test;
+import android.car.Car;
import android.car.CarManagerBase;
import android.os.IBinder;
@@ -22,10 +23,17 @@
* Only for system testing
* @hide
*/
-public class CarTestManagerBinderWrapper implements CarManagerBase {
+public class CarTestManagerBinderWrapper extends CarManagerBase {
public final IBinder binder;
public CarTestManagerBinderWrapper(IBinder binder) {
+ super(null); // This will not work safely but is only for keeping API.
+ this.binder = binder;
+ }
+
+ /** @hide */
+ public CarTestManagerBinderWrapper(Car car, IBinder binder) {
+ super(car);
this.binder = binder;
}
diff --git a/car-lib/src/android/car/trust/CarTrustAgentEnrollmentManager.java b/car-lib/src/android/car/trust/CarTrustAgentEnrollmentManager.java
index c82d515..9881420 100644
--- a/car-lib/src/android/car/trust/CarTrustAgentEnrollmentManager.java
+++ b/car-lib/src/android/car/trust/CarTrustAgentEnrollmentManager.java
@@ -24,8 +24,8 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.bluetooth.BluetoothDevice;
+import android.car.Car;
import android.car.CarManagerBase;
-import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -39,6 +39,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
+import java.util.Collections;
import java.util.List;
@@ -67,7 +68,7 @@
* @hide
*/
@SystemApi
-public final class CarTrustAgentEnrollmentManager implements CarManagerBase {
+public final class CarTrustAgentEnrollmentManager extends CarManagerBase {
private static final String TAG = "CarTrustEnrollMgr";
private static final String KEY_HANDLE = "handle";
private static final String KEY_ACTIVE = "active";
@@ -81,7 +82,6 @@
private static final int MSG_ENROLL_TOKEN_STATE_CHANGED = 7;
private static final int MSG_ENROLL_TOKEN_REMOVED = 8;
- private final Context mContext;
private final ICarTrustAgentEnrollment mEnrollmentService;
private Object mListenerLock = new Object();
@GuardedBy("mListenerLock")
@@ -114,10 +114,10 @@
/** @hide */
- public CarTrustAgentEnrollmentManager(IBinder service, Context context, Handler handler) {
- mContext = context;
+ public CarTrustAgentEnrollmentManager(Car car, IBinder service) {
+ super(car);
mEnrollmentService = ICarTrustAgentEnrollment.Stub.asInterface(service);
- mEventCallbackHandler = new EventCallbackHandler(this, handler.getLooper());
+ mEventCallbackHandler = new EventCallbackHandler(this, getEventHandler().getLooper());
}
/** @hide */
@@ -134,7 +134,7 @@
try {
mEnrollmentService.startEnrollmentAdvertising();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -146,7 +146,7 @@
try {
mEnrollmentService.stopEnrollmentAdvertising();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -161,7 +161,7 @@
try {
mEnrollmentService.enrollmentHandshakeAccepted(device);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -173,7 +173,7 @@
try {
mEnrollmentService.terminateEnrollmentHandshake();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -194,7 +194,7 @@
try {
return mEnrollmentService.isEscrowTokenActive(handle, uid);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, false);
}
}
@@ -209,7 +209,7 @@
try {
mEnrollmentService.removeEscrowToken(handle, uid);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -223,7 +223,7 @@
try {
mEnrollmentService.removeAllTrustedDevices(uid);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -238,7 +238,7 @@
try {
mEnrollmentService.setTrustedDeviceEnrollmentEnabled(isEnabled);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -253,7 +253,7 @@
try {
mEnrollmentService.setTrustedDeviceUnlockEnabled(isEnabled);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -278,7 +278,7 @@
mEnrollmentService.registerEnrollmentCallback(mListenerToEnrollmentService);
mEnrollmentCallback = callback;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
@@ -290,7 +290,7 @@
try {
mEnrollmentService.unregisterEnrollmentCallback(mListenerToEnrollmentService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
mEnrollmentCallback = null;
}
@@ -318,7 +318,7 @@
mEnrollmentService.registerBleCallback(mListenerToBleService);
mBleCallback = callback;
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
}
@@ -330,7 +330,7 @@
try {
mEnrollmentService.unregisterBleCallback(mListenerToBleService);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
mBleCallback = null;
}
@@ -351,7 +351,7 @@
try {
return mEnrollmentService.getEnrolledDeviceInfosForUser(uid);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, Collections.emptyList());
}
}
diff --git a/car-lib/src/android/car/vms/VmsPublisherClientService.java b/car-lib/src/android/car/vms/VmsPublisherClientService.java
index 309d0ee..ea75707 100644
--- a/car-lib/src/android/car/vms/VmsPublisherClientService.java
+++ b/car-lib/src/android/car/vms/VmsPublisherClientService.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.Service;
+import android.car.Car;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
@@ -114,7 +115,7 @@
try {
mVmsPublisherService.publish(token, layer, publisherId, payload);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ Car.handleRemoteExceptionFromCarService(this, e);
}
}
@@ -134,7 +135,7 @@
mVmsPublisherService.setLayersOffering(token, offering);
VmsOperationRecorder.get().setLayersOffering(offering);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ Car.handleRemoteExceptionFromCarService(this, e);
}
}
@@ -172,6 +173,7 @@
publisherId = mVmsPublisherService.getPublisherId(publisherInfo);
Log.i(TAG, "Assigned publisher ID: " + publisherId);
} catch (RemoteException e) {
+ // This will crash. To prevent crash, safer invalid return value should be defined.
throw e.rethrowFromSystemServer();
}
VmsOperationRecorder.get().getPublisherId(publisherId);
@@ -191,7 +193,7 @@
try {
return mVmsPublisherService.getSubscriptions();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return Car.handleRemoteExceptionFromCarService(this, e, null);
}
}
diff --git a/car-lib/src/android/car/vms/VmsSubscriberManager.java b/car-lib/src/android/car/vms/VmsSubscriberManager.java
index c02d3a5..edde982 100644
--- a/car-lib/src/android/car/vms/VmsSubscriberManager.java
+++ b/car-lib/src/android/car/vms/VmsSubscriberManager.java
@@ -19,6 +19,7 @@
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.car.Car;
import android.car.CarManagerBase;
import android.os.Binder;
import android.os.IBinder;
@@ -39,7 +40,7 @@
* @hide
*/
@SystemApi
-public final class VmsSubscriberManager implements CarManagerBase {
+public final class VmsSubscriberManager extends CarManagerBase {
private static final String TAG = "VmsSubscriberManager";
private final IVmsSubscriberService mVmsSubscriberService;
@@ -75,7 +76,8 @@
*
* @hide
*/
- public VmsSubscriberManager(IBinder service) {
+ public VmsSubscriberManager(Car car, IBinder service) {
+ super(car);
mVmsSubscriberService = IVmsSubscriberService.Stub.asInterface(service);
mSubscriberManagerClient = new IVmsSubscriberClient.Stub() {
@Override
@@ -133,7 +135,7 @@
try {
mVmsSubscriberService.addVmsSubscriberToNotifications(mSubscriberManagerClient);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -148,7 +150,7 @@
try {
mVmsSubscriberService.removeVmsSubscriberToNotifications(mSubscriberManagerClient);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
} finally {
synchronized (mClientCallbackLock) {
mClientCallback = null;
@@ -168,7 +170,7 @@
try {
return mVmsSubscriberService.getPublisherInfo(publisherId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -182,7 +184,7 @@
try {
return mVmsSubscriberService.getAvailableLayers();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return handleRemoteExceptionFromCarService(e, null);
}
}
@@ -199,7 +201,7 @@
mVmsSubscriberService.addVmsSubscriber(mSubscriberManagerClient, layer);
VmsOperationRecorder.get().subscribe(layer);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -218,7 +220,7 @@
mSubscriberManagerClient, layer, publisherId);
VmsOperationRecorder.get().subscribe(layer, publisherId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -231,7 +233,7 @@
mVmsSubscriberService.addVmsSubscriberPassive(mSubscriberManagerClient);
VmsOperationRecorder.get().startMonitoring();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -248,7 +250,7 @@
mVmsSubscriberService.removeVmsSubscriber(mSubscriberManagerClient, layer);
VmsOperationRecorder.get().unsubscribe(layer);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -266,7 +268,7 @@
mSubscriberManagerClient, layer, publisherId);
VmsOperationRecorder.get().unsubscribe(layer, publisherId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -278,7 +280,7 @@
mVmsSubscriberService.removeVmsSubscriberPassive(mSubscriberManagerClient);
VmsOperationRecorder.get().stopMonitoring();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -326,5 +328,9 @@
*/
@Override
public void onCarDisconnected() {
+ synchronized (mClientCallbackLock) {
+ mClientCallback = null;
+ mExecutor = null;
+ }
}
}
diff --git a/car-systemtest-lib/src/android/car/test/CarTestManager.java b/car-systemtest-lib/src/android/car/test/CarTestManager.java
index 52b01a6..3ee1067 100644
--- a/car-systemtest-lib/src/android/car/test/CarTestManager.java
+++ b/car-systemtest-lib/src/android/car/test/CarTestManager.java
@@ -27,18 +27,19 @@
* @hide
*/
@SystemApi
-public final class CarTestManager implements CarManagerBase {
+public final class CarTestManager extends CarManagerBase {
private final ICarTest mService;
- public CarTestManager(IBinder carServiceBinder) {
+ public CarTestManager(Car car, IBinder carServiceBinder) {
+ super(car);
mService = ICarTest.Stub.asInterface(carServiceBinder);
}
@Override
public void onCarDisconnected() {
- // should not happen for embedded
+ // test will fail. nothing to do.
}
/**
@@ -52,7 +53,7 @@
try {
mService.stopCarService(token);
} catch (RemoteException e) {
- handleRemoteException(e);
+ handleRemoteExceptionFromCarService(e);
}
}
@@ -66,12 +67,7 @@
try {
mService.startCarService(token);
} catch (RemoteException e) {
- handleRemoteException(e);
+ handleRemoteExceptionFromCarService(e);
}
}
-
- private static void handleRemoteException(RemoteException e) {
- // let test fail
- throw new RuntimeException(e);
- }
}
diff --git a/service/src/com/android/car/CarLocalServices.java b/service/src/com/android/car/CarLocalServices.java
index 6c756b8..ea1b6f1 100644
--- a/service/src/com/android/car/CarLocalServices.java
+++ b/service/src/com/android/car/CarLocalServices.java
@@ -17,6 +17,7 @@
package com.android.car;
import android.annotation.Nullable;
+import android.car.Car;
import android.car.hardware.power.CarPowerManager;
import android.content.Context;
import android.util.ArrayMap;
@@ -90,10 +91,12 @@
*/
@Nullable
public static CarPowerManager createCarPowerManager(Context context) {
+ // This does not require connection as binder will be passed to CarPowerManager directly.
+ Car car = new Car(context, /* service= */null, /* handler= */ null);
CarPowerManagementService service = getService(CarPowerManagementService.class);
if (service == null) {
return null;
}
- return new CarPowerManager(service, context, null);
+ return new CarPowerManager(car, service);
}
}
diff --git a/service/src/com/android/car/CarOccupantZoneService.java b/service/src/com/android/car/CarOccupantZoneService.java
index b2876f5..727d6b3 100644
--- a/service/src/com/android/car/CarOccupantZoneService.java
+++ b/service/src/com/android/car/CarOccupantZoneService.java
@@ -18,6 +18,7 @@
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.car.Car;
import android.car.CarInfoManager;
import android.car.CarOccupantZoneManager;
import android.car.CarOccupantZoneManager.OccupantZoneInfo;
@@ -168,6 +169,9 @@
private final RemoteCallbackList<ICarOccupantZoneCallback> mClientCallbacks =
new RemoteCallbackList<>();
+ @GuardedBy("mLock")
+ private int mDriverSeat = VehicleAreaSeat.SEAT_UNKNOWN;
+
public CarOccupantZoneService(Context context) {
mContext = context;
mDisplayManager = context.getSystemService(DisplayManager.class);
@@ -181,7 +185,13 @@
@Override
public void init() {
+ // This does not require connection as binder will be passed directly.
+ Car car = new Car(mContext, /* service= */null, /* handler= */ null);
+ CarInfoManager infoManager = new CarInfoManager(car, CarLocalServices.getService(
+ CarPropertyService.class));
+ int driverSeat = infoManager.getDriverSeat();
synchronized (mLock) {
+ mDriverSeat = driverSeat;
parseOccupantZoneConfigsLocked();
parseDisplayConfigsLocked();
handleActiveDisplaysLocked();
@@ -351,11 +361,12 @@
throw new RuntimeException("Format error in config_occupant_zones resource:" + msg);
}
+ // For overriding in test
@VisibleForTesting
int getDriverSeat() {
- CarInfoManager infoManager = new CarInfoManager(CarLocalServices.getService(
- CarPropertyService.class));
- return infoManager.getDriverSeat();
+ synchronized (mLock) {
+ return mDriverSeat;
+ }
}
private void parseOccupantZoneConfigsLocked() {
diff --git a/service/src/com/android/car/CarTestService.java b/service/src/com/android/car/CarTestService.java
index 8c3f64d..776fd53 100644
--- a/service/src/com/android/car/CarTestService.java
+++ b/service/src/com/android/car/CarTestService.java
@@ -22,6 +22,8 @@
import android.os.RemoteException;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
+
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
@@ -39,6 +41,9 @@
private final Context mContext;
private final ICarImpl mICarImpl;
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
private final Map<IBinder, TokenDeathRecipient> mTokens = new HashMap<>();
CarTestService(Context context, ICarImpl carImpl) {
@@ -69,7 +74,7 @@
Log.d(TAG, "stopCarService, token: " + token);
ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
- synchronized (this) {
+ synchronized (mLock) {
if (mTokens.containsKey(token)) {
Log.w(TAG, "Calling stopCarService twice with the same token.");
return;
@@ -80,7 +85,7 @@
token.linkToDeath(deathRecipient, 0);
if (mTokens.size() == 1) {
- mICarImpl.release();
+ CarServiceUtils.runOnMainSync(mICarImpl::release);
}
}
}
@@ -92,15 +97,17 @@
releaseToken(token);
}
- private synchronized void releaseToken(IBinder token) {
+ private void releaseToken(IBinder token) {
Log.d(TAG, "releaseToken, token: " + token);
- DeathRecipient deathRecipient = mTokens.remove(token);
- if (deathRecipient != null) {
- token.unlinkToDeath(deathRecipient, 0);
- }
+ synchronized (mLock) {
+ DeathRecipient deathRecipient = mTokens.remove(token);
+ if (deathRecipient != null) {
+ token.unlinkToDeath(deathRecipient, 0);
+ }
- if (mTokens.size() == 0) {
- CarServiceUtils.runOnMain(mICarImpl::init);
+ if (mTokens.size() == 0) {
+ CarServiceUtils.runOnMainSync(mICarImpl::init);
+ }
}
}
diff --git a/service/src/com/android/car/pm/ActivityBlockingActivity.java b/service/src/com/android/car/pm/ActivityBlockingActivity.java
index 9dcb70a..9756523 100644
--- a/service/src/com/android/car/pm/ActivityBlockingActivity.java
+++ b/service/src/com/android/car/pm/ActivityBlockingActivity.java
@@ -79,14 +79,19 @@
// restrictions are lifted.
// This Activity should be launched only after car service is initialized. Currently this
// Activity is only launched from CPMS. So this is safe to do.
- mCar = Car.createCar(this);
- mUxRManager = (CarUxRestrictionsManager) mCar.getCarManager(
- Car.CAR_UX_RESTRICTION_SERVICE);
- // This activity would have been launched only in a restricted state.
- // But ensuring when the service connection is established, that we are still
- // in a restricted state.
- handleUxRChange(mUxRManager.getCurrentCarUxRestrictions());
- mUxRManager.registerListener(ActivityBlockingActivity.this::handleUxRChange);
+ mCar = Car.createCar(this, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER,
+ (car, ready) -> {
+ if (!ready) {
+ return;
+ }
+ mUxRManager = (CarUxRestrictionsManager) car.getCarManager(
+ Car.CAR_UX_RESTRICTION_SERVICE);
+ // This activity would have been launched only in a restricted state.
+ // But ensuring when the service connection is established, that we are still
+ // in a restricted state.
+ handleUxRChange(mUxRManager.getCurrentCarUxRestrictions());
+ mUxRManager.registerListener(ActivityBlockingActivity.this::handleUxRChange);
+ });
}
@Override
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioTestFragment.java
index 482b246..cab9ccf 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioTestFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioTestFragment.java
@@ -21,9 +21,7 @@
import android.car.CarAppFocusManager.OnAppFocusChangedListener;
import android.car.CarAppFocusManager.OnAppFocusOwnershipCallback;
import android.car.media.CarAudioManager;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.hardware.display.DisplayManager;
@@ -35,7 +33,6 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.util.SparseArray;
@@ -133,41 +130,39 @@
private void connectCar() {
mContext = getContext();
mHandler = new Handler(Looper.getMainLooper());
- mCar = Car.createCar(mContext, new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- mAppFocusManager =
- (CarAppFocusManager) mCar.getCarManager(Car.APP_FOCUS_SERVICE);
- OnAppFocusChangedListener listener = new OnAppFocusChangedListener() {
- @Override
- public void onAppFocusChanged(int appType, boolean active) {
+ mCar = Car.createCar(mContext, /* handler= */ null,
+ Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER, (car, ready) -> {
+ if (!ready) {
+ return;
}
- };
- mAppFocusManager.addFocusListener(listener,
- CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
- mAppFocusManager.addFocusListener(listener,
- CarAppFocusManager.APP_FOCUS_TYPE_VOICE_COMMAND);
+ mAppFocusManager =
+ (CarAppFocusManager) mCar.getCarManager(Car.APP_FOCUS_SERVICE);
+ OnAppFocusChangedListener listener = new OnAppFocusChangedListener() {
+ @Override
+ public void onAppFocusChanged(int appType, boolean active) {
+ }
+ };
+ mAppFocusManager.addFocusListener(listener,
+ CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
+ mAppFocusManager.addFocusListener(listener,
+ CarAppFocusManager.APP_FOCUS_TYPE_VOICE_COMMAND);
- mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
+ mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
- //take care of zone selection
- int[] zoneList = mCarAudioManager.getAudioZoneIds();
- Integer[] zoneArray = Arrays.stream(zoneList).boxed().toArray(Integer[]::new);
- mZoneAdapter = new ArrayAdapter<>(mContext,
- android.R.layout.simple_spinner_item, zoneArray);
- mZoneAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mZoneSpinner.setAdapter(mZoneAdapter);
- mZoneSpinner.setEnabled(true);
+ //take care of zone selection
+ int[] zoneList = mCarAudioManager.getAudioZoneIds();
+ Integer[] zoneArray = Arrays.stream(zoneList).boxed().toArray(Integer[]::new);
+ mZoneAdapter = new ArrayAdapter<>(mContext,
+ android.R.layout.simple_spinner_item, zoneArray);
+ mZoneAdapter.setDropDownViewResource(
+ android.R.layout.simple_spinner_dropdown_item);
+ mZoneSpinner.setAdapter(mZoneAdapter);
+ mZoneSpinner.setEnabled(true);
- if (mCarAudioManager.isDynamicRoutingEnabled()) {
- setUpDisplayPlayer();
- }
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- });
- mCar.connect();
+ if (mCarAudioManager.isDynamicRoutingEnabled()) {
+ setUpDisplayPlayer();
+ }
+ });
}
private void initializePlayers() {
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/cluster/InstrumentClusterFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/cluster/InstrumentClusterFragment.java
index 7657c38..8886913 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/cluster/InstrumentClusterFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/cluster/InstrumentClusterFragment.java
@@ -17,6 +17,7 @@
import android.annotation.Nullable;
import android.car.Car;
+import android.car.Car.CarServiceLifecycleListener;
import android.car.CarAppFocusManager;
import android.car.CarNotConnectedException;
import android.car.cluster.navigation.NavigationState;
@@ -33,11 +34,8 @@
import android.car.cluster.navigation.NavigationState.Step;
import android.car.cluster.navigation.NavigationState.Timestamp;
import android.car.navigation.CarNavigationStatusManager;
-import android.content.ComponentName;
-import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.os.IBinder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -73,19 +71,19 @@
private NavigationStateProto[] mNavStateData;
private Button mTurnByTurnButton;
- private ServiceConnection mCarServiceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- Log.d(TAG, "Connected to Car Service");
- mCarNavigationStatusManager = (CarNavigationStatusManager) mCarApi
- .getCarManager(Car.CAR_NAVIGATION_SERVICE);
- mCarAppFocusManager = (CarAppFocusManager) mCarApi
- .getCarManager(Car.APP_FOCUS_SERVICE);
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
+ private CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> {
+ if (!ready) {
Log.d(TAG, "Disconnect from Car Service");
+ return;
+ }
+ Log.d(TAG, "Connected to Car Service");
+ try {
+ mCarNavigationStatusManager = (CarNavigationStatusManager) car.getCarManager(
+ Car.CAR_NAVIGATION_SERVICE);
+ mCarAppFocusManager = (CarAppFocusManager) car.getCarManager(
+ Car.APP_FOCUS_SERVICE);
+ } catch (CarNotConnectedException e) {
+ Log.e(TAG, "Car is not connected!", e);
}
};
@@ -117,13 +115,8 @@
private void initCarApi() {
- if (mCarApi != null && mCarApi.isConnected()) {
- mCarApi.disconnect();
- mCarApi = null;
- }
-
- mCarApi = Car.createCar(getContext(), mCarServiceConnection);
- mCarApi.connect();
+ mCarApi = Car.createCar(getContext(), /* handler= */ null,
+ Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER, mCarServiceLifecycleListener);
}
@NonNull
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/volume/VolumeTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/volume/VolumeTestFragment.java
index 73e3798..df9aa7b 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/volume/VolumeTestFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/volume/VolumeTestFragment.java
@@ -16,14 +16,12 @@
package com.google.android.car.kitchensink.volume;
import android.car.Car;
+import android.car.Car.CarServiceLifecycleListener;
import android.car.media.CarAudioManager;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.ServiceConnection;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.util.SparseIntArray;
@@ -112,20 +110,15 @@
public boolean mHasFocus;
}
- private final ServiceConnection mCarConnectionCallback =
- new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder binder) {
- Log.d(TAG, "Connected to Car Service");
- mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
- initVolumeInfo();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- Log.d(TAG, "Disconnect from Car Service");
- }
- };
+ private CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> {
+ if (!ready) {
+ Log.d(TAG, "Disconnect from Car Service");
+ return;
+ }
+ Log.d(TAG, "Connected to Car Service");
+ mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
+ initVolumeInfo();
+ };
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -161,8 +154,8 @@
mBalance = v.findViewById(R.id.balance_bar);
mBalance.setOnSeekBarChangeListener(seekListener);
- mCar = Car.createCar(getActivity(), mCarConnectionCallback);
- mCar.connect();
+ mCar = Car.createCar(getActivity(), /* handler= */ null,
+ Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER, mCarServiceLifecycleListener);
return v;
}
@@ -210,12 +203,4 @@
}
mAdapter.refreshVolumes(mVolumeInfos);
}
-
- @Override
- public void onDestroy() {
- if (mCar != null) {
- mCar.disconnect();
- }
- super.onDestroy();
- }
}
diff --git a/tests/carservice_test/src/com/android/car/MockedCarTestBase.java b/tests/carservice_test/src/com/android/car/MockedCarTestBase.java
index 091c960..82f0608 100644
--- a/tests/carservice_test/src/com/android/car/MockedCarTestBase.java
+++ b/tests/carservice_test/src/com/android/car/MockedCarTestBase.java
@@ -263,11 +263,10 @@
if (mRealCarServiceReleased) {
return; // We just want to release it once.
}
-
mRealCarServiceReleased = true; // To make sure it was called once.
Object waitForConnection = new Object();
- android.car.Car car = android.car.Car.createCar(context, new ServiceConnection() {
+ Car car = android.car.Car.createCar(context, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (waitForConnection) {
@@ -289,10 +288,10 @@
if (car.isConnected()) {
Log.i(TAG, "Connected to real car service");
CarTestManagerBinderWrapper binderWrapper =
- (CarTestManagerBinderWrapper) car.getCarManager(android.car.Car.TEST_SERVICE);
+ (CarTestManagerBinderWrapper) car.getCarManager(Car.TEST_SERVICE);
assertNotNull(binderWrapper);
- CarTestManager mgr = new CarTestManager(binderWrapper.binder);
+ CarTestManager mgr = new CarTestManager(car, binderWrapper.binder);
mgr.stopCarService(mCarServiceToken);
}
}
diff --git a/tests/carservice_unit_test/src/android/car/CarTest.java b/tests/carservice_unit_test/src/android/car/CarTest.java
index 9ac8d75..d12334d 100644
--- a/tests/carservice_unit_test/src/android/car/CarTest.java
+++ b/tests/carservice_unit_test/src/android/car/CarTest.java
@@ -22,6 +22,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.Assert.fail;
+
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.times;
@@ -177,7 +179,13 @@
runOnMainSyncSafe(() -> {
car.getServiceConnectionListener().onServiceConnected(new ComponentName("", ""),
mService);
- car.getServiceConnectionListener().onServiceDisconnected(new ComponentName("", ""));
+ try {
+ car.getServiceConnectionListener().onServiceDisconnected(new ComponentName("", ""));
+ } catch (IllegalStateException e) {
+ // expected
+ return;
+ }
+ fail("onServiceDisconnected should have triggered exception");
});
}
diff --git a/tests/carservice_unit_test/src/com/android/car/CarOccupantZoneServiceTest.java b/tests/carservice_unit_test/src/com/android/car/CarOccupantZoneServiceTest.java
index 84ce231..ae3d136 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarOccupantZoneServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarOccupantZoneServiceTest.java
@@ -26,13 +26,13 @@
import static org.testng.Assert.assertThrows;
import android.app.ActivityManager;
+import android.car.Car;
import android.car.CarOccupantZoneManager;
import android.car.CarOccupantZoneManager.OccupantZoneInfo;
import android.car.VehicleAreaSeat;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.display.DisplayManager;
-import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.view.Display;
@@ -207,8 +207,8 @@
doReturn(VehicleAreaSeat.SEAT_ROW_1_LEFT).when(mService).getDriverSeat();
doReturn(ActivityManager.getCurrentUser()).when(mService).getCurrentUser();
- mManager = new CarOccupantZoneManager(mService, mContext, new Handler(
- Looper.getMainLooper()));
+ Car car = new Car(mContext, /* service= */null, /* handler= */ null);
+ mManager = new CarOccupantZoneManager(car, mService);
}
@After