/* * Copyright (C) 2015 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; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; import android.car.cluster.CarInstrumentClusterManager; import android.car.content.pm.CarPackageManager; import android.car.diagnostic.CarDiagnosticManager; import android.car.drivingstate.CarDrivingStateManager; import android.car.drivingstate.CarUxRestrictionsManager; import android.car.hardware.CarSensorManager; import android.car.hardware.CarVendorExtensionManager; import android.car.hardware.cabin.CarCabinManager; import android.car.hardware.hvac.CarHvacManager; import android.car.hardware.power.CarPowerManager; import android.car.hardware.property.CarPropertyManager; import android.car.media.CarAudioManager; import android.car.navigation.CarNavigationStatusManager; import android.car.settings.CarConfigurationManager; import android.car.storagemonitoring.CarStorageMonitoringManager; import android.car.test.CarTestManagerBinderWrapper; import android.car.vms.VmsSubscriberManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.HashMap; /** * Top level car API for embedded Android Auto deployments. * This API works only for devices with {@link PackageManager#FEATURE_AUTOMOTIVE} * Calling this API on a device with no such feature will lead to an exception. */ public final class Car { /** * Represent the version of Car API. This is only updated when there is API change. * 1 : N * 2 : O * 3 : O-MR1 */ public static final int VERSION = 3; /** Service name for {@link CarSensorManager}, to be used in {@link #getCarManager(String)}. */ public static final String SENSOR_SERVICE = "sensor"; /** Service name for {@link CarInfoManager}, to be used in {@link #getCarManager(String)}. */ public static final String INFO_SERVICE = "info"; /** Service name for {@link CarAppFocusManager}. */ public static final String APP_FOCUS_SERVICE = "app_focus"; /** Service name for {@link CarPackageManager} */ public static final String PACKAGE_SERVICE = "package"; /** Service name for {@link CarAudioManager} */ public static final String AUDIO_SERVICE = "audio"; /** Service name for {@link CarNavigationStatusManager} */ public static final String CAR_NAVIGATION_SERVICE = "car_navigation_service"; /** * Service name for {@link CarInstrumentClusterManager} * @hide */ public static final String CAR_INSTRUMENT_CLUSTER_SERVICE = "cluster_service"; /** * @hide */ @SystemApi public static final String CABIN_SERVICE = "cabin"; /** * @hide */ @SystemApi public static final String DIAGNOSTIC_SERVICE = "diagnostic"; /** * @hide */ @SystemApi public static final String HVAC_SERVICE = "hvac"; /** * @hide */ @SystemApi public static final String POWER_SERVICE = "power"; /** * @hide */ @SystemApi public static final String PROJECTION_SERVICE = "projection"; /** * @hide */ @SystemApi public static final String PROPERTY_SERVICE = "property"; /** * @hide */ @SystemApi public static final String VENDOR_EXTENSION_SERVICE = "vendor_extension"; /** * @hide */ public static final String BLUETOOTH_SERVICE = "car_bluetooth"; /** * @hide */ @SystemApi public static final String VMS_SUBSCRIBER_SERVICE = "vehicle_map_subscriber_service"; /** * Service name for {@link CarDrivingStateManager} * @hide */ @SystemApi public static final String CAR_DRIVING_STATE_SERVICE = "drivingstate"; /** * Service name for {@link CarUxRestrictionsManager} */ public static final String CAR_UX_RESTRICTION_SERVICE = "uxrestriction"; /** * Service name for {@link android.car.settings.CarConfigurationManager} */ public static final String CAR_CONFIGURATION_SERVICE = "configuration"; /** * @hide */ @SystemApi public static final String STORAGE_MONITORING_SERVICE = "storage_monitoring"; /** * Service for testing. This is system app only feature. * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}. * @hide */ @SystemApi public static final String TEST_SERVICE = "car-service-test"; /** Permission necessary to access car's mileage information. * @hide */ @SystemApi public static final String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE"; /** Permission necessary to access car's energy information. */ public static final String PERMISSION_ENERGY = "android.car.permission.CAR_ENERGY"; /** Permission necessary to access car's VIN information */ public static final String PERMISSION_IDENTIFICATION = "android.car.permission.CAR_IDENTIFICATION"; /** Permission necessary to access car's speed. */ public static final String PERMISSION_SPEED = "android.car.permission.CAR_SPEED"; /** Permission necessary to access car's dynamics state. * @hide */ @SystemApi public static final String PERMISSION_CAR_DYNAMICS_STATE = "android.car.permission.CAR_DYNAMICS_STATE"; /** Permission necessary to access car's fuel door and ev charge port. */ public static final String PERMISSION_ENERGY_PORTS = "android.car.permission.CAR_ENERGY_PORTS"; /** Permission necessary to read car's lights information. * @hide */ @SystemApi public static final String PERMISSION_EXTERIOR_LIGHTS = "android.car.permission.CAR_EXTERIOR_LIGHTS"; /** Permission necessary to control car's exterior lights. * @hide */ @SystemApi public static final String PERMISSION_CONTROL_EXTERIOR_LIGHTS = "android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS"; /** Permission necessary to access car's powertrain information.*/ public static final String PERMISSION_POWERTRAIN = "android.car.permission.CAR_POWERTRAIN"; /** * Permission necessary to change car audio volume through {@link CarAudioManager}. */ public static final String PERMISSION_CAR_CONTROL_AUDIO_VOLUME = "android.car.permission.CAR_CONTROL_AUDIO_VOLUME"; /** * Permission necessary to change car audio settings through {@link CarAudioManager}. * @hide */ public static final String PERMISSION_CAR_CONTROL_AUDIO_SETTINGS = "android.car.permission.CAR_CONTROL_AUDIO_SETTINGS"; /** * Permission necessary to use {@link CarNavigationStatusManager}. */ public static final String PERMISSION_CAR_NAVIGATION_MANAGER = "android.car.permission.CAR_NAVIGATION_MANAGER"; /** * Permission necessary to start activities in the instrument cluster through * {@link CarInstrumentClusterManager} * * @hide */ @SystemApi public static final String PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL = "android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL"; /** * Application must have this permission in order to be launched in the instrument cluster * display. * * @hide */ public static final String PERMISSION_CAR_DISPLAY_IN_CLUSTER = "android.car.permission.CAR_DISPLAY_IN_CLUSTER"; /** Permission necessary to use {@link CarInfoManager}. */ public static final String PERMISSION_CAR_INFO = "android.car.permission.CAR_INFO"; /** Permission necessary to read temperature of car's exterior environment. */ public static final String PERMISSION_EXTERIOR_ENVIRONMENT = "android.car.permission.CAR_EXTERIOR_ENVIRONMENT"; /** * Permission necessary to access car specific communication channel. * @hide */ @SystemApi public static final String PERMISSION_VENDOR_EXTENSION = "android.car.permission.CAR_VENDOR_EXTENSION"; /** * @hide */ @SystemApi public static final String PERMISSION_CONTROL_APP_BLOCKING = "android.car.permission.CONTROL_APP_BLOCKING"; /** * Permission necessary to access Car Cabin APIs. * @hide */ @SystemApi public static final String PERMISSION_ADJUST_CAR_CABIN = "android.car.permission.ADJUST_CAR_CABIN"; /** * Permission necessary to access car's engine information. * @hide */ @SystemApi public static final String PERMISSION_CAR_ENGINE_DETAILED = "android.car.permission.CAR_ENGINE_DETAILED"; /** * Permission necessary to access car's tire pressure information. * @hide */ @SystemApi public static final String PERMISSION_TIRES = "android.car.permission.CAR_TIRES"; /** * Permission necessary to control car's door. * @hide */ @SystemApi public static final String PERMISSION_CONTROL_CAR_DOORS = "android.car.permission.CONTROL_CAR_DOORS"; /** * Permission necessary to control car's windows. * @hide */ @SystemApi public static final String PERMISSION_CONTROL_CAR_WINDOWS = "android.car.permission.CONTROL_CAR_WINDOWS"; /** * Permission necessary to control car's seats. * @hide */ @SystemApi public static final String PERMISSION_CONTROL_CAR_SEATS = "android.car.permission.CONTROL_CAR_SEATS"; /** * Permission necessary to control car's mirrors. * @hide */ @SystemApi public static final String PERMISSION_CONTROL_CAR_MIRRORS = "android.car.permission.CONTROL_CAR_MIRRORS"; /** * Permission necessary to access Car HVAC APIs. * @hide */ @SystemApi public static final String PERMISSION_CONTROL_CAR_CLIMATE = "android.car.permission.CONTROL_CAR_CLIMATE"; /** * Permission necessary to access Car POWER APIs. * @hide */ @SystemApi public static final String PERMISSION_CAR_POWER = "android.car.permission.CAR_POWER"; /** * Permission necessary to access Car PROJECTION system APIs. * @hide */ @SystemApi public static final String PERMISSION_CAR_PROJECTION = "android.car.permission.CAR_PROJECTION"; /** * Permission necessary to mock vehicle hal for testing. * @hide * @deprecated mocking vehicle HAL in car service is no longer supported. */ @SystemApi public static final String PERMISSION_MOCK_VEHICLE_HAL = "android.car.permission.CAR_MOCK_VEHICLE_HAL"; /** * Permission necessary to access CarTestService. * @hide */ @SystemApi public static final String PERMISSION_CAR_TEST_SERVICE = "android.car.permission.CAR_TEST_SERVICE"; /** * Permission necessary to access CarDrivingStateService to get a Car's driving state. * @hide */ @SystemApi public static final String PERMISSION_CAR_DRIVING_STATE = "android.car.permission.CAR_DRIVING_STATE"; /** * Permissions necessary to access VMS publisher APIs. * * @hide */ @SystemApi public static final String PERMISSION_VMS_PUBLISHER = "android.car.permission.VMS_PUBLISHER"; /** * Permissions necessary to access VMS subscriber APIs. * * @hide */ @SystemApi public static final String PERMISSION_VMS_SUBSCRIBER = "android.car.permission.VMS_SUBSCRIBER"; /** * Permissions necessary to read diagnostic information, including vendor-specific bits. * * @hide */ @SystemApi public static final String PERMISSION_CAR_DIAGNOSTIC_READ_ALL = "android.car.permission.CAR_DIAGNOSTICS"; /** * Permissions necessary to clear diagnostic information. * * @hide */ @SystemApi public static final String PERMISSION_CAR_DIAGNOSTIC_CLEAR = "android.car.permission.CLEAR_CAR_DIAGNOSTICS"; /** * Permissions necessary to clear diagnostic information. * * @hide */ @SystemApi public static final String PERMISSION_STORAGE_MONITORING = "android.car.permission.STORAGE_MONITORING"; /** Type of car connection: platform runs directly in car. */ public static final int CONNECTION_TYPE_EMBEDDED = 5; /** @hide */ @IntDef({CONNECTION_TYPE_EMBEDDED}) @Retention(RetentionPolicy.SOURCE) public @interface ConnectionType {} /** * CarXyzService throws IllegalStateException with this message is re-thrown as * {@link CarNotConnectedException}. * * @hide */ public static final String CAR_NOT_CONNECTED_EXCEPTION_MSG = "CarNotConnected"; /** * Activity Action: Provide media playing through a media template app. *
Input: String extra mapped by {@link android.app.SearchManager#QUERY} is the query * used to start the media. String extra mapped by {@link #CAR_EXTRA_MEDIA_PACKAGE} is the * package name of the media app which user wants to play media on. *
Output: nothing.
*/
public static final String CAR_INTENT_ACTION_MEDIA_TEMPLATE =
"android.car.intent.action.MEDIA_TEMPLATE";
/**
* Used as a string extra field with {@link #CAR_INTENT_ACTION_MEDIA_TEMPLATE} to specify the
* media app that user wants to start the media on. Note: this is not the templated media app.
*/
public static final String CAR_EXTRA_MEDIA_PACKAGE = "android.car.intent.extra.MEDIA_PACKAGE";
/** @hide */
public static final String CAR_SERVICE_INTERFACE_NAME = "android.car.ICar";
private static final String CAR_SERVICE_PACKAGE = "com.android.car";
private static final String CAR_SERVICE_CLASS = "com.android.car.CarService";
private static final long CAR_SERVICE_BIND_RETRY_INTERVAL_MS = 500;
private static final long CAR_SERVICE_BIND_MAX_RETRY = 20;
private final Context mContext;
@GuardedBy("this")
private ICar mService;
private final boolean mOwnsService;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
@GuardedBy("this")
private int mConnectionState;
@GuardedBy("this")
private int mConnectionRetryCount;
private final Runnable mConnectionRetryRunnable = new Runnable() {
@Override
public void run() {
startCarService();
}
};
private final Runnable mConnectionRetryFailedRunnable = new Runnable() {
@Override
public void run() {
mServiceConnectionListener.onServiceDisconnected(new ComponentName(CAR_SERVICE_PACKAGE,
CAR_SERVICE_CLASS));
}
};
private final ServiceConnection mServiceConnectionListener =
new ServiceConnection () {
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (Car.this) {
mService = ICar.Stub.asInterface(service);
mConnectionState = STATE_CONNECTED;
}
mServiceConnectionListenerClient.onServiceConnected(name, service);
}
public void onServiceDisconnected(ComponentName name) {
synchronized (Car.this) {
mService = null;
if (mConnectionState == STATE_DISCONNECTED) {
return;
}
mConnectionState = STATE_DISCONNECTED;
}
// unbind explicitly here.
disconnect();
mServiceConnectionListenerClient.onServiceDisconnected(name);
}
};
private final ServiceConnection mServiceConnectionListenerClient;
private final Object mCarManagerLock = new Object();
@GuardedBy("mCarManagerLock")
private final HashMap