// Signature format: 2.0
package android.support.car {

  public class Car {
    method public void connect() throws java.lang.IllegalStateException;
    method public static android.support.car.Car createCar(android.content.Context, android.support.car.CarConnectionCallback, @Nullable android.os.Handler);
    method public static android.support.car.Car createCar(android.content.Context, android.support.car.CarConnectionCallback);
    method public void disconnect();
    method public Object getCarManager(String) throws android.support.car.CarNotConnectedException;
    method public <T> T getCarManager(Class<T>) throws android.support.car.CarNotConnectedException;
    method public boolean isConnected();
    method public boolean isConnecting();
    field public static final String APP_FOCUS_SERVICE = "app_focus";
    field public static final String AUDIO_SERVICE = "audio";
    field public static final String INFO_SERVICE = "info";
    field public static final String NAVIGATION_STATUS_SERVICE = "car_navigation_service";
    field public static final String PERMISSION_CAR_NAVIGATION_MANAGER = "android.car.permission.PERMISSION_CAR_NAVIGATION_MANAGER";
    field public static final String PERMISSION_VENDOR_EXTENSION = "android.car.permission.CAR_VENDOR_EXTENSION";
    field public static final String SENSOR_SERVICE = "sensor";
  }

  public abstract class CarAppFocusManager {
    ctor public CarAppFocusManager();
    method public abstract void abandonAppFocus(android.support.car.CarAppFocusManager.OnAppFocusOwnershipCallback, int);
    method public abstract void abandonAppFocus(android.support.car.CarAppFocusManager.OnAppFocusOwnershipCallback);
    method public abstract void addFocusListener(android.support.car.CarAppFocusManager.OnAppFocusChangedListener, int) throws android.support.car.CarNotConnectedException;
    method public abstract boolean isOwningFocus(int, android.support.car.CarAppFocusManager.OnAppFocusOwnershipCallback) throws android.support.car.CarNotConnectedException;
    method public abstract void removeFocusListener(android.support.car.CarAppFocusManager.OnAppFocusChangedListener, int);
    method public abstract void removeFocusListener(android.support.car.CarAppFocusManager.OnAppFocusChangedListener);
    method public abstract int requestAppFocus(int, android.support.car.CarAppFocusManager.OnAppFocusOwnershipCallback) throws android.support.car.CarNotConnectedException, java.lang.SecurityException;
    field public static final int APP_FOCUS_REQUEST_FAILED = 0; // 0x0
    field public static final int APP_FOCUS_REQUEST_SUCCEEDED = 1; // 0x1
    field public static final int APP_FOCUS_TYPE_NAVIGATION = 1; // 0x1
  }

  public static interface CarAppFocusManager.OnAppFocusChangedListener {
    method public void onAppFocusChanged(android.support.car.CarAppFocusManager, int, boolean);
  }

  public static interface CarAppFocusManager.OnAppFocusOwnershipCallback {
    method public void onAppFocusOwnershipGranted(android.support.car.CarAppFocusManager, int);
    method public void onAppFocusOwnershipLost(android.support.car.CarAppFocusManager, int);
  }

  public abstract class CarConnectionCallback {
    ctor public CarConnectionCallback();
    method public abstract void onConnected(android.support.car.Car);
    method public abstract void onDisconnected(android.support.car.Car);
  }

  public abstract class CarInfoManager {
    ctor public CarInfoManager();
    method public abstract int getDriverPosition() throws android.support.car.CarNotConnectedException;
    method public abstract float getEvBatteryCapacity() throws android.support.car.CarNotConnectedException;
    method public abstract int[] getEvConnectorTypes() throws android.support.car.CarNotConnectedException;
    method public abstract float getFuelCapacity() throws android.support.car.CarNotConnectedException;
    method public abstract int[] getFuelTypes() throws android.support.car.CarNotConnectedException;
    method @Nullable public abstract String getHeadunitManufacturer() throws android.support.car.CarNotConnectedException;
    method @Nullable public abstract String getHeadunitModel() throws android.support.car.CarNotConnectedException;
    method @Nullable public abstract String getHeadunitSoftwareBuild() throws android.support.car.CarNotConnectedException;
    method @Nullable public abstract String getHeadunitSoftwareVersion() throws android.support.car.CarNotConnectedException;
    method @Nullable public abstract String getManufacturer() throws android.support.car.CarNotConnectedException;
    method @Nullable public abstract String getModel() throws android.support.car.CarNotConnectedException;
    method @Nullable public abstract String getModelYear() throws android.support.car.CarNotConnectedException;
    method @Nullable public abstract String getVehicleId() throws android.support.car.CarNotConnectedException;
    field public static final int DRIVER_SIDE_CENTER = 3; // 0x3
    field public static final int DRIVER_SIDE_LEFT = 1; // 0x1
    field public static final int DRIVER_SIDE_RIGHT = 2; // 0x2
    field public static final int DRIVER_SIDE_UNKNOWN = 0; // 0x0
  }

  public class CarNotConnectedException extends java.lang.Exception {
    ctor public CarNotConnectedException();
    ctor public CarNotConnectedException(String);
    ctor public CarNotConnectedException(String, Throwable);
    ctor public CarNotConnectedException(Exception);
  }

}

package android.support.car.annotation {

  @java.lang.annotation.Target(java.lang.annotation.ElementType.FIELD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface ValueTypeDef {
    method public abstract Class<?> type() default java.lang.Object.class;
  }

  @java.lang.annotation.Target(java.lang.annotation.ElementType.FIELD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public @interface VersionDef {
    method public abstract int version() default 1;
  }

}

package android.support.car.hardware {

  public class CarSensorEvent {
    method public android.support.car.hardware.CarSensorEvent.CompassData getCompassData();
    method public android.support.car.hardware.CarSensorEvent.DrivingStatusData getDrivingStatusData();
    method public android.support.car.hardware.CarSensorEvent.NightData getNightData();
    method public android.support.car.hardware.CarSensorEvent.ParkingBrakeData getParkingBrakeData();
    field public static final int DRIVE_STATUS_FULLY_RESTRICTED = 31; // 0x1f
    field public static final int DRIVE_STATUS_LIMIT_MESSAGE_LEN = 16; // 0x10
    field public static final int DRIVE_STATUS_NO_CONFIG = 8; // 0x8
    field public static final int DRIVE_STATUS_NO_KEYBOARD_INPUT = 2; // 0x2
    field public static final int DRIVE_STATUS_NO_VIDEO = 1; // 0x1
    field public static final int DRIVE_STATUS_NO_VOICE_INPUT = 4; // 0x4
    field public static final int DRIVE_STATUS_UNRESTRICTED = 0; // 0x0
    field public static final int INDEX_COMPASS_BEARING = 0; // 0x0
    field public static final int INDEX_COMPASS_PITCH = 1; // 0x1
    field public static final int INDEX_COMPASS_ROLL = 2; // 0x2
    field public static final int INDEX_WHEEL_DISTANCE_FRONT_LEFT = 1; // 0x1
    field public static final int INDEX_WHEEL_DISTANCE_FRONT_RIGHT = 2; // 0x2
    field public static final int INDEX_WHEEL_DISTANCE_REAR_LEFT = 4; // 0x4
    field public static final int INDEX_WHEEL_DISTANCE_REAR_RIGHT = 3; // 0x3
    field public static final int INDEX_WHEEL_DISTANCE_RESET_COUNT = 0; // 0x0
    field public final float[] floatValues;
    field public final int[] intValues;
    field public final long[] longValues;
    field public final int sensorType;
    field public final long timestamp;
  }

  public static class CarSensorEvent.CompassData {
    field public final float bearing;
    field public final float pitch;
    field public final float roll;
    field public final long timestamp;
  }

  public static class CarSensorEvent.DrivingStatusData {
    method public boolean isConfigurationRestricted();
    method public boolean isFullyRestricted();
    method public boolean isKeyboardRestricted();
    method public boolean isMessageLengthRestricted();
    method public boolean isVideoRestricted();
    method public boolean isVoiceRestricted();
    field public final int status;
    field public final long timestamp;
  }

  public static class CarSensorEvent.NightData {
    field public final boolean isNightMode;
    field public final long timestamp;
  }

  public static class CarSensorEvent.ParkingBrakeData {
    field public final boolean isEngaged;
    field public final long timestamp;
  }

  public abstract class CarSensorManager {
    ctor public CarSensorManager();
    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, "android.car.permission.CAR_SPEED", "android.car.permission.CAR_MILEAGE", "android.car.permission.CAR_ENERGY", "android.car.permission.VEHICLE_DYNAMICS_STATE"}, conditional=true) public abstract boolean addListener(android.support.car.hardware.CarSensorManager.OnSensorChangedListener, int, int) throws android.support.car.CarNotConnectedException, java.lang.IllegalArgumentException;
    method public abstract android.support.car.hardware.CarSensorEvent getLatestSensorEvent(int) throws android.support.car.CarNotConnectedException;
    method public abstract int[] getSupportedSensors() throws android.support.car.CarNotConnectedException;
    method public abstract boolean isSensorSupported(int) throws android.support.car.CarNotConnectedException;
    method public abstract void removeListener(android.support.car.hardware.CarSensorManager.OnSensorChangedListener);
    method public abstract void removeListener(android.support.car.hardware.CarSensorManager.OnSensorChangedListener, int);
    field public static final int SENSOR_RATE_FASTEST = 100; // 0x64
    field public static final int SENSOR_RATE_NORMAL = 1; // 0x1
    field public static final int SENSOR_TYPE_ABS_ACTIVE = 24; // 0x18
    field public static final int SENSOR_TYPE_COMPASS = 1; // 0x1
    field public static final int SENSOR_TYPE_DRIVING_STATUS = 11; // 0xb
    field public static final int SENSOR_TYPE_EV_BATTERY_CHARGE_RATE = 31; // 0x1f
    field public static final int SENSOR_TYPE_EV_BATTERY_LEVEL = 28; // 0x1c
    field public static final int SENSOR_TYPE_EV_CHARGE_PORT_CONNECTED = 30; // 0x1e
    field public static final int SENSOR_TYPE_EV_CHARGE_PORT_OPEN = 29; // 0x1d
    field public static final int SENSOR_TYPE_FUEL_DOOR_OPEN = 27; // 0x1b
    field public static final int SENSOR_TYPE_NIGHT = 9; // 0x9
    field public static final int SENSOR_TYPE_PARKING_BRAKE = 6; // 0x6
    field public static final int SENSOR_TYPE_TRACTION_CONTROL_ACTIVE = 25; // 0x19
    field public static final int SENSOR_TYPE_WHEEL_TICK_DISTANCE = 23; // 0x17
  }

  public static interface CarSensorManager.OnSensorChangedListener {
    method public void onSensorChanged(android.support.car.hardware.CarSensorManager, android.support.car.hardware.CarSensorEvent);
  }

}

package android.support.car.media {

  public abstract class CarAudioManager {
    ctor public CarAudioManager();
    method @RequiresPermission(android.Manifest.permission.RECORD_AUDIO) public abstract android.support.car.media.CarAudioRecord createCarAudioRecord(int) throws android.support.car.CarNotConnectedException, java.lang.SecurityException;
    method public abstract android.media.AudioFormat getAudioRecordAudioFormat() throws android.support.car.CarNotConnectedException;
    method public abstract int getAudioRecordMaxBufferSize() throws android.support.car.CarNotConnectedException;
    method public abstract int getAudioRecordMinBufferSize() throws android.support.car.CarNotConnectedException;
    method public abstract boolean isAudioRecordSupported() throws android.support.car.CarNotConnectedException;
  }

  public abstract class CarAudioRecord {
    ctor public CarAudioRecord();
    method public abstract int getAudioSessionId() throws android.support.car.CarNotConnectedException;
    method public abstract int getBufferSize() throws android.support.car.CarNotConnectedException;
    method public abstract int getRecordingState() throws android.support.car.CarNotConnectedException;
    method public abstract int getState() throws android.support.car.CarNotConnectedException;
    method public abstract int read(byte[], int, int) throws android.support.car.CarNotConnectedException, java.lang.IllegalStateException;
    method public abstract void release();
    method public abstract void startRecording() throws android.support.car.CarNotConnectedException;
    method public abstract void stop();
  }

}

package android.support.car.navigation {

  public class CarNavigationInstrumentCluster {
    method public int getImageColorDepthBits();
    method public int getImageHeight();
    method public int getImageWidth();
    method public int getMinIntervalMillis();
    method public int getType();
    method public boolean supportsCustomImages();
    field public static final int CLUSTER_TYPE_CUSTOM_IMAGES_SUPPORTED = 1; // 0x1
    field public static final int CLUSTER_TYPE_IMAGE_CODES_ONLY = 2; // 0x2
  }

  public abstract class CarNavigationStatusManager {
    ctor public CarNavigationStatusManager();
    method public abstract void addListener(android.support.car.navigation.CarNavigationStatusManager.CarNavigationCallback) throws android.support.car.CarNotConnectedException;
    method public abstract void removeListener();
    method public abstract void sendEvent(int, android.os.Bundle) throws android.support.car.CarNotConnectedException;
  }

  public static interface CarNavigationStatusManager.CarNavigationCallback {
    method public void onInstrumentClusterStarted(android.support.car.navigation.CarNavigationStatusManager, android.support.car.navigation.CarNavigationInstrumentCluster);
    method public void onInstrumentClusterStopped(android.support.car.navigation.CarNavigationStatusManager);
  }

}

