aboutsummaryrefslogtreecommitdiff
path: root/car-lib/src/android/car/drivingstate
diff options
context:
space:
mode:
authorRam Periathiruvadi <ramperry@google.com>2017-11-17 16:48:37 -0800
committerRam Periathiruvadi <ramperry@google.com>2018-01-22 14:58:18 -0800
commit25c16f168c685c11065836d2682dfb1dfef2b60d (patch)
tree8474f360339f1dcf9437aea7d8ebf861c4640134 /car-lib/src/android/car/drivingstate
parent89a9ead4f494db2db0e9c72fb6b4c3dc0dd04333 (diff)
downloadCar-25c16f168c685c11065836d2682dfb1dfef2b60d.tar.gz
Car Managers for driving state & UX restrictions
Adding new Car Managers and Services to expose the car's driving state and the mapped UX Restrictions for that driving state. CarDrivingStateManager is exposed as a SystemApi, whereas CarUXRestrictionsManager is exposed as a public API for apps to react. Bug: b/68716688, b/69859786, b/72052159 Test: KitchenSink app can listen to both driving state and UXR changes. Change-Id: I962e0bdde4ceef5be203409ca26cf51a68dd84ca
Diffstat (limited to 'car-lib/src/android/car/drivingstate')
-rw-r--r--car-lib/src/android/car/drivingstate/CarDrivingStateEvent.aidl19
-rw-r--r--car-lib/src/android/car/drivingstate/CarDrivingStateEvent.java113
-rw-r--r--car-lib/src/android/car/drivingstate/CarDrivingStateManager.java228
-rw-r--r--car-lib/src/android/car/drivingstate/CarUXRestrictionsEvent.aidl19
-rw-r--r--car-lib/src/android/car/drivingstate/CarUXRestrictionsEvent.java101
-rw-r--r--car-lib/src/android/car/drivingstate/CarUXRestrictionsManager.java229
-rw-r--r--car-lib/src/android/car/drivingstate/ICarDrivingState.aidl34
-rw-r--r--car-lib/src/android/car/drivingstate/ICarDrivingStateChangeListener.aidl27
-rw-r--r--car-lib/src/android/car/drivingstate/ICarUXRestrictions.aidl33
-rw-r--r--car-lib/src/android/car/drivingstate/ICarUXRestrictionsChangeListener.aidl26
10 files changed, 829 insertions, 0 deletions
diff --git a/car-lib/src/android/car/drivingstate/CarDrivingStateEvent.aidl b/car-lib/src/android/car/drivingstate/CarDrivingStateEvent.aidl
new file mode 100644
index 0000000000..ac800ae1d5
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/CarDrivingStateEvent.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+parcelable CarDrivingStateEvent;
diff --git a/car-lib/src/android/car/drivingstate/CarDrivingStateEvent.java b/car-lib/src/android/car/drivingstate/CarDrivingStateEvent.java
new file mode 100644
index 0000000000..e3fa2ea8e5
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/CarDrivingStateEvent.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Driving State related events. Driving State of a car conveys if the car is currently parked,
+ * idling or moving.
+ *
+ * @hide
+ */
+@SystemApi
+public class CarDrivingStateEvent implements Parcelable {
+
+ // New Driving States
+ /**
+ * This is when we don't have enough information to infer the car's driving state.
+ */
+ public static final int DRIVING_STATE_UNKNOWN = -1;
+ /**
+ * Car is parked - Gear is in Parked mode.
+ */
+ public static final int DRIVING_STATE_PARKED = 0;
+ /**
+ * Car is idling. Gear is not in Parked mode and Speed of the vehicle is zero.
+ * TODO: (b/72157869) - Should speed that differentiates moving vs idling be configurable?
+ */
+ public static final int DRIVING_STATE_IDLING = 1;
+ /**
+ * Car is moving. Gear is not in parked mode and speed of the vehicle is non zero.
+ */
+ public static final int DRIVING_STATE_MOVING = 2;
+
+ /** @hide */
+ @IntDef({DRIVING_STATE_UNKNOWN,
+ DRIVING_STATE_PARKED,
+ DRIVING_STATE_IDLING,
+ DRIVING_STATE_MOVING})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CarDrivingState {
+ }
+
+ /**
+ * Time at which this driving state was inferred based on the car's sensors.
+ * It is the elapsed time in nanoseconds since system boot.
+ */
+ public final long timeStamp;
+
+ /**
+ * The Car's driving state.
+ */
+ @CarDrivingState
+ public final int eventValue;
+
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(eventValue);
+ dest.writeLong(timeStamp);
+ }
+
+ public static final Parcelable.Creator<CarDrivingStateEvent> CREATOR
+ = new Parcelable.Creator<CarDrivingStateEvent>() {
+ public CarDrivingStateEvent createFromParcel(Parcel in) {
+ return new CarDrivingStateEvent(in);
+ }
+
+ public CarDrivingStateEvent[] newArray(int size) {
+ return new CarDrivingStateEvent[size];
+ }
+ };
+
+ public CarDrivingStateEvent(int value, long time) {
+ eventValue = value;
+ timeStamp = time;
+ }
+
+ private CarDrivingStateEvent(Parcel in) {
+ eventValue = in.readInt();
+ timeStamp = in.readLong();
+ }
+
+ @Override
+ public String toString() {
+ return eventValue + " " + timeStamp;
+ }
+}
diff --git a/car-lib/src/android/car/drivingstate/CarDrivingStateManager.java b/car-lib/src/android/car/drivingstate/CarDrivingStateManager.java
new file mode 100644
index 0000000000..8c2a24fde3
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/CarDrivingStateManager.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.car.Car;
+import android.car.CarManagerBase;
+import android.car.CarNotConnectedException;
+import android.car.drivingstate.ICarDrivingState;
+import android.content.Context;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+import java.lang.ref.WeakReference;
+
+/**
+ * API to register and get driving state related information in a car.
+ * @hide
+ */
+@SystemApi
+public final class CarDrivingStateManager implements 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;
+ private CarDrivingStateChangeListenerToService mListenerToService;
+
+
+ /** @hide */
+ public CarDrivingStateManager(IBinder service, Context context, Handler handler) {
+ mContext = context;
+ mDrivingService = ICarDrivingState.Stub.asInterface(service);
+ mEventCallbackHandler = new EventCallbackHandler(this, handler.getLooper());
+ }
+
+ /** @hide */
+ @Override
+ public synchronized void onCarDisconnected() {
+ mListenerToService = null;
+ mDrvStateEventListener = null;
+ }
+
+ /**
+ * Listener Interface for clients to implement to get updated on driving state changes.
+ */
+ public interface CarDrivingStateEventListener {
+ /**
+ * Called when the car's driving state changes.
+ * @param event Car's driving state.
+ */
+ void onDrivingStateChanged(CarDrivingStateEvent event);
+ }
+
+ /**
+ * Register a {@link CarDrivingStateEventListener} to listen for driving state changes.
+ *
+ * @param listener {@link CarDrivingStateEventListener}
+ */
+ public synchronized void registerListener(@NonNull CarDrivingStateEventListener listener)
+ throws CarNotConnectedException, IllegalArgumentException {
+ if (listener == null) {
+ if (VDBG) {
+ Log.v(TAG, "registerCarDrivingStateEventListener(): null listener");
+ }
+ throw new IllegalArgumentException("Listener is null");
+ }
+ // Check if the listener has been already registered for this event type
+ if (mDrvStateEventListener != null) {
+ if (DBG) {
+ Log.d(TAG, "Listener already registered");
+ }
+ return;
+ }
+ mDrvStateEventListener = listener;
+ try {
+ if (mListenerToService == null) {
+ mListenerToService = new CarDrivingStateChangeListenerToService(this);
+ }
+ // register to the Service for getting notified
+ mDrivingService.registerDrivingStateChangeListener(mListenerToService);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not register a listener to Driving State Service " + e);
+ throw new CarNotConnectedException(e);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Could not register a listener to Driving State Service " + e);
+ Car.checkCarNotConnectedExceptionFromCarService(e);
+ }
+ }
+
+ /**
+ * Unregister the registered {@link CarDrivingStateEventListener} for the given driving event
+ * type.
+ */
+ public synchronized void unregisterListener()
+ throws CarNotConnectedException {
+ if (mDrvStateEventListener == null) {
+ if (DBG) {
+ Log.d(TAG, "Listener was not previously registered");
+ }
+ return;
+ }
+ try {
+ mDrivingService.unregisterDrivingStateChangeListener(mListenerToService);
+ mDrvStateEventListener = null;
+ mListenerToService = null;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not unregister listener from Driving State Service " + e);
+ throw new CarNotConnectedException(e);
+ }
+ }
+
+ /**
+ * Get the current value of the car's driving state.
+ *
+ * @return {@link CarDrivingStateEvent} corresponding to the given eventType
+ */
+ @Nullable
+ public CarDrivingStateEvent getCurrentCarDrivingState()
+ throws CarNotConnectedException {
+ try {
+ return mDrivingService.getCurrentDrivingState();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not get current driving state " + e);
+ throw new CarNotConnectedException(e);
+ }
+ }
+
+ /**
+ * Class that implements the listener interface and gets called back from the
+ * {@link com.android.car.CarDrivingStateService} across the binder interface.
+ */
+ private static class CarDrivingStateChangeListenerToService extends
+ ICarDrivingStateChangeListener.Stub {
+ private final WeakReference<CarDrivingStateManager> mDrvStateMgr;
+
+ public CarDrivingStateChangeListenerToService(CarDrivingStateManager manager) {
+ mDrvStateMgr = new WeakReference<>(manager);
+ }
+
+ @Override
+ public void onDrivingStateChanged(CarDrivingStateEvent event) {
+ CarDrivingStateManager manager = mDrvStateMgr.get();
+ if (manager != null) {
+ manager.handleDrivingStateChanged(event);
+ }
+ }
+ }
+
+ /**
+ * Gets the {@link CarDrivingStateEvent} from the service listener
+ * {@link CarDrivingStateChangeListenerToService} and dispatches it to a handler provided
+ * to the manager
+ *
+ * @param event {@link CarDrivingStateEvent} that has been registered to listen on
+ */
+ private void handleDrivingStateChanged(CarDrivingStateEvent event) {
+ // send a message to the handler
+ mEventCallbackHandler.sendMessage(
+ mEventCallbackHandler.obtainMessage(MSG_HANDLE_DRIVING_STATE_CHANGE, event));
+
+ }
+
+ /**
+ * Callback Handler to handle dispatching the driving state changes to the corresponding
+ * listeners
+ */
+ private static final class EventCallbackHandler extends Handler {
+ private final WeakReference<CarDrivingStateManager> mDrvStateMgr;
+
+ public EventCallbackHandler(CarDrivingStateManager manager, Looper looper) {
+ super(looper);
+ mDrvStateMgr = new WeakReference<>(manager);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ CarDrivingStateManager mgr = mDrvStateMgr.get();
+ if (mgr != null) {
+ mgr.dispatchDrivingStateChangeToClient((CarDrivingStateEvent) msg.obj);
+ }
+ }
+
+ }
+
+ /**
+ * Checks for the listener to {@link CarDrivingStateEvent} and calls it back
+ * in the callback handler thread
+ *
+ * @param event {@link CarDrivingStateEvent}
+ */
+ private void dispatchDrivingStateChangeToClient(CarDrivingStateEvent event) {
+ if (event == null) {
+ return;
+ }
+ CarDrivingStateEventListener listener;
+ synchronized (this) {
+ listener = mDrvStateEventListener;
+ }
+ if (listener != null) {
+ listener.onDrivingStateChanged(event);
+ }
+ }
+
+}
diff --git a/car-lib/src/android/car/drivingstate/CarUXRestrictionsEvent.aidl b/car-lib/src/android/car/drivingstate/CarUXRestrictionsEvent.aidl
new file mode 100644
index 0000000000..3e37dbbdd6
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/CarUXRestrictionsEvent.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+parcelable CarUXRestrictionsEvent;
diff --git a/car-lib/src/android/car/drivingstate/CarUXRestrictionsEvent.java b/car-lib/src/android/car/drivingstate/CarUXRestrictionsEvent.java
new file mode 100644
index 0000000000..a6fa1aaf42
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/CarUXRestrictionsEvent.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+import android.annotation.IntDef;
+import android.os.Parcel;
+import android.os.Parcelable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Car UX Restrictions related event. This contains information on the set of UX restrictions
+ * that is in place due to the car's driving state.
+ */
+public class CarUXRestrictionsEvent implements Parcelable {
+
+ // UXRestrictions TODO: (b/69859857) - make it configurable
+ /**
+ * No UX Restrictions. Vehicle Optimized apps are allowed to display non Drive Optimized
+ * Activities.
+ */
+ public static final int UXR_NO_RESTRICTIONS = 0;
+ /**
+ * UX Restrictions fully in place. Only Drive Optimized Activities that are optimized to handle
+ * the UX restrictions can run.
+ * TODO: (b/72155508) - Finalize what these restrictions are
+ */
+ public static final int UXR_FULLY_RESTRICTED = 31;
+
+ @IntDef({UXR_NO_RESTRICTIONS,
+ UXR_FULLY_RESTRICTED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CarUXRestrictions {
+ }
+
+ /**
+ * Time at which this UX restriction event was deduced based on the car's driving state.
+ * It is the elapsed time in nanoseconds since system boot.
+ */
+ public final long timeStamp;
+
+ /**
+ * UX Restriction in effect.
+ * TODO: (b/72155508) If/When we add more granular UX restrictions, this will be a list of
+ * restrictions.
+ */
+ @CarUXRestrictions
+ public final int eventValue;
+
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(eventValue);
+ dest.writeLong(timeStamp);
+ }
+
+ public static final Parcelable.Creator<CarUXRestrictionsEvent> CREATOR
+ = new Parcelable.Creator<CarUXRestrictionsEvent>() {
+ public CarUXRestrictionsEvent createFromParcel(Parcel in) {
+ return new CarUXRestrictionsEvent(in);
+ }
+
+ public CarUXRestrictionsEvent[] newArray(int size) {
+ return new CarUXRestrictionsEvent[size];
+ }
+ };
+
+ public CarUXRestrictionsEvent(int value, long time) {
+ eventValue = value;
+ timeStamp = time;
+ }
+
+ private CarUXRestrictionsEvent(Parcel in) {
+ eventValue = in.readInt();
+ timeStamp = in.readLong();
+ }
+
+ @Override
+ public String toString() {
+ return eventValue + " " + timeStamp;
+ }
+}
diff --git a/car-lib/src/android/car/drivingstate/CarUXRestrictionsManager.java b/car-lib/src/android/car/drivingstate/CarUXRestrictionsManager.java
new file mode 100644
index 0000000000..10a39ac2b1
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/CarUXRestrictionsManager.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.car.Car;
+import android.car.CarManagerBase;
+import android.car.CarNotConnectedException;
+import android.car.drivingstate.ICarUXRestrictions;
+import android.content.Context;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+import java.lang.ref.WeakReference;
+
+/**
+ * API to register and get the User Experience restrictions imposed based on the car's driving
+ * state.
+ */
+public final class CarUXRestrictionsManager implements CarManagerBase {
+ private static final String TAG = "CarUXRManager";
+ private static final boolean DBG = false;
+ private static final boolean VDBG = false;
+ private static final int MSG_HANDLE_UX_RESTRICTIONS_CHANGE = 0;
+
+ private final Context mContext;
+ private final ICarUXRestrictions mUXRService;
+ private final EventCallbackHandler mEventCallbackHandler;
+ private CarUXRestrictionsEventListener mUXRListener;
+ private CarUXRestrictionsChangeListenerToService mListenerToService;
+
+
+ /** @hide */
+ public CarUXRestrictionsManager(IBinder service, Context context, Handler handler) {
+ mContext = context;
+ mUXRService = ICarUXRestrictions.Stub.asInterface(service);
+ mEventCallbackHandler = new EventCallbackHandler(this, handler.getLooper());
+ }
+
+ /** @hide */
+ @Override
+ public synchronized void onCarDisconnected() {
+ mListenerToService = null;
+ mUXRListener = null;
+ }
+
+ /**
+ * Listener Interface for clients to implement to get updated on driving state related
+ * changes.
+ */
+ public interface CarUXRestrictionsEventListener {
+ /**
+ * Called when the UX restrictions due to a car's driving state changes.
+ * @param event The new UX restriction event
+ */
+ void onUXRestrictionsChanged(CarUXRestrictionsEvent event);
+ }
+
+ /**
+ * Register a {@link CarUXRestrictionsEventListener} for listening to changes in the
+ * UX Restrictions to adhere to.
+ * <p>
+ * If a listener has already been registered, it has to be unregistered before registering
+ * the new one.
+ *
+ * @param listener {@link CarUXRestrictionsEventListener}
+ */
+ public synchronized void registerListener(@NonNull CarUXRestrictionsEventListener listener)
+ throws CarNotConnectedException, IllegalArgumentException {
+ if (listener == null) {
+ if (VDBG) {
+ Log.v(TAG, "registerCarUXRestrictionsEventListener(): null listener");
+ }
+ throw new IllegalArgumentException("Listener is null");
+ }
+ // Check if the listener has been already registered for this event type
+ if (mUXRListener != null) {
+ if (DBG) {
+ Log.d(TAG, "Listener already registered listener");
+ }
+ return;
+ }
+ mUXRListener = listener;
+ try {
+ if (mListenerToService == null) {
+ mListenerToService = new CarUXRestrictionsChangeListenerToService(this);
+ }
+ // register to the Service to listen for changes.
+ mUXRService.registerUXRestrictionsChangeListener(mListenerToService);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not register a listener to Driving State Service " + e);
+ throw new CarNotConnectedException(e);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Could not register a listener to Driving State Service " + e);
+ Car.checkCarNotConnectedExceptionFromCarService(e);
+ }
+ }
+
+ /**
+ * Unregister the registered {@link CarUXRestrictionsEventListener}
+ */
+ public synchronized void unregisterListener()
+ throws CarNotConnectedException {
+ if (mUXRListener == null) {
+ if (DBG) {
+ Log.d(TAG, "Listener was not previously registered");
+ }
+ return;
+ }
+ try {
+ mUXRService.unregisterUXRestrictionsChangeListener(mListenerToService);
+ mUXRListener = null;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not unregister listener from Driving State Service " + e);
+ throw new CarNotConnectedException(e);
+ }
+ }
+
+ /**
+ * Get the current UX restrictions {@link CarUXRestrictionsEvent} in place.
+ *
+ * @return current UX restrictions that is in effect.
+ */
+ @Nullable
+ public CarUXRestrictionsEvent getCurrentCarUXRestrictions()
+ throws CarNotConnectedException {
+ try {
+ return mUXRService.getCurrentUXRestrictions();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not get current driving state " + e);
+ throw new CarNotConnectedException(e);
+ }
+ }
+
+ /**
+ * Class that implements the listener interface and gets called back from the
+ * {@link com.android.car.CarDrivingStateService} across the binder interface.
+ */
+ private static class CarUXRestrictionsChangeListenerToService extends
+ ICarUXRestrictionsChangeListener.Stub {
+ private final WeakReference<CarUXRestrictionsManager> mUXRestrictionsManager;
+
+ public CarUXRestrictionsChangeListenerToService(CarUXRestrictionsManager manager) {
+ mUXRestrictionsManager = new WeakReference<>(manager);
+ }
+
+ @Override
+ public void onUXRestrictionsChanged(CarUXRestrictionsEvent event) {
+ CarUXRestrictionsManager manager = mUXRestrictionsManager.get();
+ if (manager != null) {
+ manager.handleUXRestrictionsChanged(event);
+ }
+ }
+ }
+
+ /**
+ * Gets the {@link CarUXRestrictionsEvent} from the service listener
+ * {@link CarUXRestrictionsChangeListenerToService} and dispatches it to a handler provided
+ * to the manager
+ *
+ * @param event {@link CarUXRestrictionsEvent} that has been registered to listen on
+ */
+ private void handleUXRestrictionsChanged(CarUXRestrictionsEvent event) {
+ // send a message to the handler
+ mEventCallbackHandler.sendMessage(
+ mEventCallbackHandler.obtainMessage(MSG_HANDLE_UX_RESTRICTIONS_CHANGE, event));
+
+ }
+
+ /**
+ * Callback Handler to handle dispatching the driving event changes to the corresponding
+ * listeners
+ */
+ private static final class EventCallbackHandler extends Handler {
+ private final WeakReference<CarUXRestrictionsManager> mUXRestrictionsManager;
+
+ public EventCallbackHandler(CarUXRestrictionsManager manager, Looper looper) {
+ super(looper);
+ mUXRestrictionsManager = new WeakReference<>(manager);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ CarUXRestrictionsManager mgr = mUXRestrictionsManager.get();
+ if (mgr != null) {
+ mgr.dispatchUXRChangeToClient((CarUXRestrictionsEvent) msg.obj);
+ }
+ }
+
+ }
+
+ /**
+ * Checks for the listeners to list of {@link CarUXRestrictionsEvent} and calls them back
+ * in the callback handler thread
+ *
+ * @param event {@link CarUXRestrictionsEvent}
+ */
+ private void dispatchUXRChangeToClient(CarUXRestrictionsEvent event) {
+ if (event == null) {
+ return;
+ }
+ CarUXRestrictionsEventListener listener;
+ synchronized (this) {
+ listener = mUXRListener;
+ }
+ if (listener != null) {
+ listener.onUXRestrictionsChanged(event);
+ }
+ }
+
+}
diff --git a/car-lib/src/android/car/drivingstate/ICarDrivingState.aidl b/car-lib/src/android/car/drivingstate/ICarDrivingState.aidl
new file mode 100644
index 0000000000..30f1542d27
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/ICarDrivingState.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+import android.car.drivingstate.CarDrivingStateEvent;
+import android.car.drivingstate.ICarDrivingStateChangeListener;
+
+/**
+ * Binder interface for {@link android.car.drivingstate.CarDrivingStateManager}.
+ * Check {@link android.car.drivingstate.CarDrivingStateManager} APIs for expected behavior of
+ * each call.
+ *
+ * @hide
+ */
+
+interface ICarDrivingState {
+ void registerDrivingStateChangeListener(in ICarDrivingStateChangeListener listener) = 0;
+ void unregisterDrivingStateChangeListener(in ICarDrivingStateChangeListener listener) = 1;
+ CarDrivingStateEvent getCurrentDrivingState() = 2;
+}
diff --git a/car-lib/src/android/car/drivingstate/ICarDrivingStateChangeListener.aidl b/car-lib/src/android/car/drivingstate/ICarDrivingStateChangeListener.aidl
new file mode 100644
index 0000000000..357d7d6b84
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/ICarDrivingStateChangeListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+import android.car.drivingstate.CarDrivingStateEvent;
+
+/**
+ * Binder callback for onDrivingStateChange.
+ * @hide
+ */
+oneway interface ICarDrivingStateChangeListener {
+ void onDrivingStateChanged(in CarDrivingStateEvent event) = 0;
+}
diff --git a/car-lib/src/android/car/drivingstate/ICarUXRestrictions.aidl b/car-lib/src/android/car/drivingstate/ICarUXRestrictions.aidl
new file mode 100644
index 0000000000..0e3f1c3ff9
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/ICarUXRestrictions.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+import android.car.drivingstate.CarUXRestrictionsEvent;
+import android.car.drivingstate.ICarUXRestrictionsChangeListener;
+
+/**
+ * Binder interface for {@link android.car.drivingstate.CarUXRestrictionsManager}.
+ * Check {@link android.car.drivingstate.CarUXRestrictionsManager} APIs for expected behavior of
+ * each call.
+ *
+ * @hide
+ */
+interface ICarUXRestrictions {
+ void registerUXRestrictionsChangeListener(in ICarUXRestrictionsChangeListener listener) = 0;
+ void unregisterUXRestrictionsChangeListener(in ICarUXRestrictionsChangeListener listener) = 1;
+ CarUXRestrictionsEvent getCurrentUXRestrictions() = 2;
+}
diff --git a/car-lib/src/android/car/drivingstate/ICarUXRestrictionsChangeListener.aidl b/car-lib/src/android/car/drivingstate/ICarUXRestrictionsChangeListener.aidl
new file mode 100644
index 0000000000..be411330bc
--- /dev/null
+++ b/car-lib/src/android/car/drivingstate/ICarUXRestrictionsChangeListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.drivingstate;
+
+import android.car.drivingstate.CarUXRestrictionsEvent;
+
+/**
+ * Binder callback for onUXRestrictionsChanged.
+ */
+oneway interface ICarUXRestrictionsChangeListener {
+ void onUXRestrictionsChanged(in CarUXRestrictionsEvent event) = 0;
+}