/*
 * 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 static android.car.CarLibLog.TAG_CAR;
import static android.car.feature.Flags.FLAG_ANDROID_VIC_VEHICLE_PROPERTIES;

import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.Activity;
import android.app.Service;
import android.car.admin.CarDevicePolicyManager;
import android.car.annotation.MandatoryFeature;
import android.car.annotation.OptionalFeature;
import android.car.app.CarActivityManager;
import android.car.builtin.os.BuildHelper;
import android.car.builtin.os.ServiceManagerHelper;
import android.car.cluster.CarInstrumentClusterManager;
import android.car.cluster.ClusterActivityState;
import android.car.cluster.ClusterHomeManager;
import android.car.content.pm.CarPackageManager;
import android.car.diagnostic.CarDiagnosticManager;
import android.car.drivingstate.CarDrivingStateManager;
import android.car.drivingstate.CarUxRestrictionsManager;
import android.car.evs.CarEvsManager;
import android.car.feature.Flags;
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.hardware.property.ICarProperty;
import android.car.input.CarInputManager;
import android.car.media.CarAudioManager;
import android.car.media.CarMediaIntents;
import android.car.media.CarMediaManager;
import android.car.navigation.CarNavigationStatusManager;
import android.car.occupantawareness.OccupantAwarenessManager;
import android.car.occupantconnection.CarOccupantConnectionManager;
import android.car.os.CarPerformanceManager;
import android.car.remoteaccess.CarRemoteAccessManager;
import android.car.storagemonitoring.CarStorageMonitoringManager;
import android.car.telemetry.CarTelemetryManager;
import android.car.test.CarTestManager;
import android.car.user.CarUserManager;
import android.car.user.ExperimentalCarUserManager;
import android.car.vms.VmsClientManager;
import android.car.vms.VmsSubscriberManager;
import android.car.watchdog.CarWatchdogManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
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.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.TransactionTooLargeException;
import android.util.ArrayMap;
import android.util.Log;

import com.android.car.internal.VisibleForHiddenApiCheck;
import com.android.car.internal.common.CommonConstants;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 *   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 {

    /**
     * System property to define platform minor version.
     *
     * <p>Value is int string. Check {@link #PROPERTY_PLATFORM_MINOR_INT} for further details.
     * If not set, default value of {@code 0} is assumed.
     */
    private static final String PROPERTY_PLATFORM_MINOR_VERSION =
            "ro.android.car.version.platform_minor";

    /**
     * @deprecated - use {@code getCarApiVersion().getMajorVersion()} instead
     */
    @Deprecated
    public static final int API_VERSION_MAJOR_INT = 34;

    /**
     * @deprecated - use {@code getCarApiVersion().getMinorVersion()} instead
     */
    @Deprecated
    public static final int API_VERSION_MINOR_INT = 0;


    /**
     * @deprecated - use {@code getPlatformApiVersion().getMinorVersion()} instead
     */
    @Deprecated
    public static final int PLATFORM_VERSION_MINOR_INT = SystemProperties
            .getInt(PROPERTY_PLATFORM_MINOR_VERSION, /* def= */ 0);

    private static final CarVersion CAR_VERSION = CarVersion.newInstance("Car.CAR_VERSION",
            API_VERSION_MAJOR_INT, API_VERSION_MINOR_INT);

    private static final PlatformVersion PLATFORM_VERSION;

    /**
     * @hide
     */
    @TestApi
    public static final String PROPERTY_EMULATED_PLATFORM_VERSION_MAJOR =
            "com.android.car.internal.debug.platform_major_version";
    /**
     * @hide
     */
    @TestApi
    public static final String PROPERTY_EMULATED_PLATFORM_VERSION_MINOR =
            "com.android.car.internal.debug.platform_minor_version";

    static {
        PlatformVersion emulated = null;
        if (!BuildHelper.isUserBuild()) {
            int major = SystemProperties.getInt(PROPERTY_EMULATED_PLATFORM_VERSION_MAJOR, -1);
            if (major != -1) {
                int minor = SystemProperties.getInt(PROPERTY_EMULATED_PLATFORM_VERSION_MINOR,
                        PLATFORM_VERSION_MINOR_INT);
                emulated = android.car.PlatformVersion.newInstance("EMULATED", major, minor);
                Log.i(TAG_CAR, "Emulating PLATFORM_VERSION version: " + emulated);
            }
        }
        PLATFORM_VERSION =
                emulated != null ? emulated : PlatformVersion.getCurrentPlatformVersionForMinor(
                        "Car.PLATFORM_VERSION", PLATFORM_VERSION_MINOR_INT);
    }

    // Car service registry information.
    // This information never changes after the static initialization completes.
    private static final Map<Class<?>, String> CAR_SERVICE_NAMES =
            new ArrayMap<Class<?>, String>(36);

    /**
     * Binder service name of car service registered to service manager.
     *
     * @hide
     */
    @VisibleForHiddenApiCheck
    public static final String CAR_SERVICE_BINDER_SERVICE_NAME = "car_service";

    /**
     * This represents AndroidManifest meta-data to tell that {@code Activity} is optimized for
     * driving distraction.
     *
     * <p>Activities without this meta-data can be blocked while car is in moving / driving state.
     *
     * <p>Note that having this flag does not guarantee that the {@code Activity} will be always
     * allowed for all driving states.
     *
     * <p>For this meta-data, android:value can be {@code true} (=optimized) or {@code false}.
     *
     * <p>Example usage:
     * <xml><meta-data android:name="distractionOptimized" android:value="true"/></xml>
     */
    @SuppressLint("IntentName")
    public static final String META_DATA_DISTRACTION_OPTIMIZED = "distractionOptimized";

    /**
     * This represents AndroidManifest meta-data to tell that {@code Application} requires specific
     * car features to work.
     *
     * <p>Apps like launcher or installer app can use this information to filter out apps
     * not usable in a specific car. This meta-data is not necessary for mandatory features.
     *
     * <p>For this meta-data, android:value should contain the feature name string defined by
     * {@code OptionalFeature} or {@code ExperimentalFeature} annotations.
     *
     * <p>Example usage:
     * <xml><meta-data android:name="requires-car-feature" android:value="diagnostic"/></xml>
     */
    @SuppressLint("IntentName")
    public static final String META_DATA_REQUIRES_CAR_FEATURE = "requires-car-feature";

    /**
     * Service name for {@link CarSensorManager}, to be used in {@link #getCarManager(String)}.
     *
     * @deprecated  {@link CarSensorManager} is deprecated. Use {@link CarPropertyManager} instead.
     */
    @MandatoryFeature
    @Deprecated
    public static final String SENSOR_SERVICE = "sensor";

    /** Service name for {@link CarInfoManager}, to be used in {@link #getCarManager(String)}. */
    @MandatoryFeature
    public static final String INFO_SERVICE = "info";

    /** Service name for {@link CarAppFocusManager}. */
    @MandatoryFeature
    public static final String APP_FOCUS_SERVICE = "app_focus";

    /** Service name for {@link CarPackageManager} */
    @MandatoryFeature
    public static final String PACKAGE_SERVICE = "package";

    /** Service name for {@link CarAudioManager} */
    @MandatoryFeature
    public static final String AUDIO_SERVICE = "audio";

    /** Service name for {@code CarNavigationStatusManager} */
    @OptionalFeature
    public static final String CAR_NAVIGATION_SERVICE = "car_navigation_service";

    /**
     * Service name for {@link CarOccupantConnectionManager}.
     *
     * @hide
     */
    @OptionalFeature
    @SystemApi
    public static final String CAR_OCCUPANT_CONNECTION_SERVICE = "car_occupant_connection_service";

    /**
     * Service name for {@link CarRemoteDeviceManager}.
     *
     * @hide
     */
    @OptionalFeature
    @SystemApi
    public static final String CAR_REMOTE_DEVICE_SERVICE = "car_remote_device_service";

    /** Service name for {@link CarOccupantZoneManager} */
    @MandatoryFeature
    public static final String CAR_OCCUPANT_ZONE_SERVICE = "car_occupant_zone_service";

    /**
     * Service name for {@link CarUserManager}
     *
     * @hide
     */
    @MandatoryFeature
    @SystemApi
    public static final String CAR_USER_SERVICE = "car_user_service";

    /**
     * Service name for {@link ExperimentalCarUserManager}
     *
     * @hide
     * @deprecated {@link ExperimentalCarUserManager} was an experimental feature and is no longer
     * supported. It will be marked {@code @removed} in the next major release and hard removed in
     * the release after that.
     */
    @Deprecated
    @OptionalFeature
    public static final String EXPERIMENTAL_CAR_USER_SERVICE = "experimental_car_user_service";

    /**
     * Service name for ExperimentalCarKeyguardService
     *
     * @hide
     */
    @OptionalFeature
    public static final String EXPERIMENTAL_CAR_KEYGUARD_SERVICE =
            "experimental_car_keyguard_service";

    /**
     * Service name for {@link CarDevicePolicyManager}
     *
     * @hide
     */
    @MandatoryFeature
    @SystemApi
    public static final String CAR_DEVICE_POLICY_SERVICE = "car_device_policy_service";

    /**
     * Service name for {@link CarInstrumentClusterManager}
     *
     * @deprecated CarInstrumentClusterManager is being deprecated
     * @hide
     */
    @OptionalFeature
    @Deprecated
    public static final String CAR_INSTRUMENT_CLUSTER_SERVICE = "cluster_service";

    /**
     * Service name for {@link CarCabinManager}.
     *
     * @deprecated {@link CarCabinManager} is deprecated. Use {@link CarPropertyManager} instead.
     * @hide
     */
    @MandatoryFeature
    @Deprecated
    @SystemApi
    public static final String CABIN_SERVICE = "cabin";

    /**
     * Service name for {@link android.car.diagnostic.CarDiagnosticManager}.
     * @hide
     */
    @OptionalFeature
    @SystemApi
    public static final String DIAGNOSTIC_SERVICE = "diagnostic";

    /**
     * Service name for {@link CarHvacManager}
     * @deprecated {@link CarHvacManager} is deprecated. Use {@link CarPropertyManager} instead.
     * @hide
     */
    @MandatoryFeature
    @Deprecated
    @SystemApi
    public static final String HVAC_SERVICE = "hvac";

    /**
     * Service name for {@link CarPowerManager}
     */
    @MandatoryFeature
    public static final String POWER_SERVICE = "power";

    /**
     * Service name for {@link android.car.CarProjectionManager}
     * @hide
     */
    @MandatoryFeature
    @SystemApi
    public static final String PROJECTION_SERVICE = "projection";

    /**
     * Service name for {@link CarPropertyManager}
     */
    @MandatoryFeature
    public static final String PROPERTY_SERVICE = "property";

    /**
     * Service name for {@link CarVendorExtensionManager}
     *
     * @deprecated {@link CarVendorExtensionManager} is deprecated.
     * Use {@link CarPropertyManager} instead.
     * @hide
     */
    @MandatoryFeature
    @Deprecated
    @SystemApi
    public static final String VENDOR_EXTENSION_SERVICE = "vendor_extension";

    /**
     * Service name for {@link VmsClientManager}
     *
     * @hide
     */
    @OptionalFeature
    @SystemApi
    public static final String VEHICLE_MAP_SERVICE = "vehicle_map_service";

    /**
     * Service name for {@link VmsSubscriberManager}
     *
     * @deprecated {@link VmsSubscriberManager} is deprecated. Use {@link VmsClientManager} instead.
     * @hide
     */
    @OptionalFeature
    @Deprecated
    @SystemApi
    public static final String VMS_SUBSCRIBER_SERVICE = "vehicle_map_subscriber_service";

    /**
     * Service name for {@link CarDrivingStateManager}
     * @hide
     */
    @MandatoryFeature
    @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.occupantawareness.OccupantAwarenessManager}
     * @hide
     */
    @OptionalFeature
    @SystemApi
    public static final String OCCUPANT_AWARENESS_SERVICE = "occupant_awareness";

    /**
     * Service name for {@link android.car.media.CarMediaManager}
     * @hide
     */
    @MandatoryFeature
    @SystemApi
    public static final String CAR_MEDIA_SERVICE = "car_media";

    /**
     * Service name for {@link android.car.CarBugreportManager}
     * @hide
     */
    @MandatoryFeature
    @SystemApi
    public static final String CAR_BUGREPORT_SERVICE = "car_bugreport";

    /**
     * Service name for {@link android.car.storagemonitoring.CarStorageMonitoringManager}
     * @hide
     */
    @OptionalFeature
    @SystemApi
    public static final String STORAGE_MONITORING_SERVICE = "storage_monitoring";

    /**
     * Service name for {@link android.car.watchdog.CarWatchdogManager}
     */
    @MandatoryFeature
    public static final String CAR_WATCHDOG_SERVICE = "car_watchdog";

    /**
     * Service name for {@link android.car.os.CarPerformanceManager}
     *
     * @hide
     */
    @MandatoryFeature
    @SystemApi
    public static final String CAR_PERFORMANCE_SERVICE = "car_performance";

    /**
     * Service name for {@link android.car.input.CarInputManager}
     * @hide
     */
    @MandatoryFeature
    @SystemApi
    public static final String CAR_INPUT_SERVICE = "android.car.input";

    /**
     * Service name for {@link android.car.cluster.ClusterHomeManager}
     * @hide
     */
    @OptionalFeature
    public static final String CLUSTER_HOME_SERVICE = "cluster_home_service";

    /**
     * Service for testing. This is system app only feature.
     * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}.
     * @hide
     */
    @MandatoryFeature
    @SystemApi
    public static final String TEST_SERVICE = "car-service-test";

    /**
     * Service name for {@link android.car.evs.CarEvsManager}
     *
     * @hide
     */
    @OptionalFeature
    @SystemApi
    public static final String CAR_EVS_SERVICE = "car_evs_service";

    /**
     * Service name for {@link android.car.telemetry.CarTelemetryManager}
     *
     * @hide
     */
    @OptionalFeature
    @SystemApi
    public static final String CAR_TELEMETRY_SERVICE = "car_telemetry_service";

    /**
     * Service name for {@link android.car.app.CarActivityManager}
     *
     * @hide
     */
    @MandatoryFeature
    @SystemApi
    public static final String CAR_ACTIVITY_SERVICE = "car_activity_service";

    /**
     * Service name for {@link android.car.remoteaccess.CarRemoteAccessManager}
     *
     * @hide
     */
    @OptionalFeature
    @SystemApi
    public static final String CAR_REMOTE_ACCESS_SERVICE = "car_remote_access_service";

    /**
     * Permission necessary to read driver monitoring systems settings information.
     *
     * Examples of settings include the ENABLED properties for the supported driver monitoring
     * features.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_READ_DRIVER_MONITORING_SETTINGS =
            "android.car.permission.READ_DRIVER_MONITORING_SETTINGS";

    /**
     * Permission necessary to control driver monitoring systems settings information.
     *
     * Examples of settings include the ENABLED properties for the supported driver monitoring
     * features.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_DRIVER_MONITORING_SETTINGS =
            "android.car.permission.CONTROL_DRIVER_MONITORING_SETTINGS";

    /**
     * Permission necessary to read driver monitoring systems states information.
     *
     * Examples of states include the STATE and WARNING properties for the supported driver
     * monitoring features.
     *
     * This is different from {@link PERMISSION_READ_DRIVER_MONITORING_SETTINGS}, which allows an
     * app to read the system settings, such as whether the system is enabled or disabled.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_READ_DRIVER_MONITORING_STATES =
            "android.car.permission.READ_DRIVER_MONITORING_STATES";

    /** 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 control car's EV charge settings. */
    public static final String PERMISSION_CONTROL_CAR_ENERGY =
            "android.car.permission.CONTROL_CAR_ENERGY";

    /**
     * Permission necessary to change value of car's range remaining.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_ADJUST_RANGE_REMAINING =
            "android.car.permission.ADJUST_RANGE_REMAINING";

    /** 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 control car's dynamics state.
     *  @hide
     */
    @FlaggedApi(Flags.FLAG_ANDROID_VIC_VEHICLE_PROPERTIES)
    @SystemApi
    public static final String PERMISSION_CONTROL_CAR_DYNAMICS_STATE =
            "android.car.permission.CONTROL_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 control car's fuel door and ev charge port.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_ENERGY_PORTS =
            "android.car.permission.CONTROL_CAR_ENERGY_PORTS";

    /**
     * Permission necessary to read car's exterior lights information.
     *  @hide
     */
    @SystemApi
    public static final String PERMISSION_EXTERIOR_LIGHTS =
            "android.car.permission.CAR_EXTERIOR_LIGHTS";

    /**
     * Permission necessary to read car's interior lights information.
     */
    public static final String PERMISSION_READ_INTERIOR_LIGHTS =
            "android.car.permission.READ_CAR_INTERIOR_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 control car's interior lights.
     */
    public static final String PERMISSION_CONTROL_INTERIOR_LIGHTS =
            "android.car.permission.CONTROL_CAR_INTERIOR_LIGHTS";

    /** Permission necessary to access car's powertrain information.*/
    public static final String PERMISSION_POWERTRAIN = "android.car.permission.CAR_POWERTRAIN";

    /**
     * Permission necessary to control car's powertrain information.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_POWERTRAIN =
            "android.car.permission.CONTROL_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}.
     */
    public static final String PERMISSION_CAR_CONTROL_AUDIO_SETTINGS =
            "android.car.permission.CAR_CONTROL_AUDIO_SETTINGS";

    /**
     * Permission necessary to receive full audio ducking events from car audio focus handler.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_RECEIVE_CAR_AUDIO_DUCKING_EVENTS =
            "android.car.permission.RECEIVE_CAR_AUDIO_DUCKING_EVENTS";

    /**
     * Permission necessary to use {@code 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";

    /**
     * Permission necessary to listen for the instrument cluster's navigation state changes.
     *
     * @hide
     */
    public static final String PERMISSION_CAR_MONITOR_CLUSTER_NAVIGATION_STATE =
            "android.car.permission.CAR_MONITOR_CLUSTER_NAVIGATION_STATE";


    /**
     * Application must have this permission in order to be launched in the instrument cluster
     * display.
     *
     * @hide
     */
    @VisibleForHiddenApiCheck
    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 access privileged car info. */
    public static final String PERMISSION_PRIVILEGED_CAR_INFO =
            "android.car.permission.PRIVILEGED_CAR_INFO";

    /**
     * Permission necessary to read information of vendor properties' permissions.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_READ_CAR_VENDOR_PERMISSION_INFO =
            "android.car.permission.READ_CAR_VENDOR_PERMISSION_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'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 access car's property {@link VehiclePropertyIds#EPOCH_TIME}.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CAR_EPOCH_TIME = "android.car.permission.CAR_EPOCH_TIME";

    /**
     * Permission necessary to access car's steering angle information.
     */
    public static final String PERMISSION_READ_STEERING_STATE =
            "android.car.permission.READ_CAR_STEERING";

    /**
     * Permission necessary to read and write display units for distance, fuel volume, tire pressure
     * and ev battery.
     */
    public static final String PERMISSION_READ_DISPLAY_UNITS =
            "android.car.permission.READ_CAR_DISPLAY_UNITS";

    /**
     * Permission necessary to control display units for distance, fuel volume, tire pressure
     * and ev battery. Currently, all display unit properties require both {@code
     * PERMISSION_CONTROL_DISPLAY_UNITS} and {@code PERMISSION_VENDOR_EXTENSION} to be granted in
     * order to write to them.
     */
    public static final String PERMISSION_CONTROL_DISPLAY_UNITS =
            "android.car.permission.CONTROL_CAR_DISPLAY_UNITS";

    /**
     * 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 glove box.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_GLOVE_BOX =
            "android.car.permission.CONTROL_GLOVE_BOX";
    /**
     * 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 enable/disable a seat's ability to deploy airbag(s) when triggered
     * (e.g. by a crash).
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_CAR_AIRBAGS =
            "android.car.permission.CONTROL_CAR_AIRBAGS";


    /**
     * Permission necessary to access restrictive car power management APIs.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CAR_POWER = "android.car.permission.CAR_POWER";

    /**
     * Permission necessary to read the current power policy or be notified of power policy change.
     */
    public static final String PERMISSION_READ_CAR_POWER_POLICY =
            "android.car.permission.READ_CAR_POWER_POLICY";

    /**
     * Permission necessary to apply a new power policy.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_CAR_POWER_POLICY =
            "android.car.permission.CONTROL_CAR_POWER_POLICY";

    /**
     * Permission necessary to adjust the shutdown process.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_SHUTDOWN_PROCESS =
            "android.car.permission.CONTROL_SHUTDOWN_PROCESS";

    /**
     * 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 access projection status.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CAR_PROJECTION_STATUS =
            "android.car.permission.ACCESS_CAR_PROJECTION_STATUS";

    /**
     * Permission necessary to mock vehicle hal for testing.
     * @hide
     * @deprecated mocking vehicle HAL in car service is no longer supported.
     */
    @Deprecated
    @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";

    /**
     * Permission necessary to access VMS client service.
     *
     * @hide
     */
    @VisibleForHiddenApiCheck
    public static final String PERMISSION_BIND_VMS_CLIENT =
            "android.car.permission.BIND_VMS_CLIENT";

    /**
     * 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";

    /**
     * Permission necessary to read ultrasonics sensor data.
     * @hide
     */
    @FlaggedApi(FLAG_ANDROID_VIC_VEHICLE_PROPERTIES)
    @SystemApi
    public static final String PERMISSION_READ_ULTRASONICS_SENSOR_DATA =
            "android.car.permission.READ_ULTRASONICS_SENSOR_DATA";

    /**
     * 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";

    /**
     * Permission necessary to configure UX restrictions through {@link CarUxRestrictionsManager}.
     *
     * @hide
     */
    @VisibleForHiddenApiCheck
    @SystemApi
    public static final String PERMISSION_CAR_UX_RESTRICTIONS_CONFIGURATION =
            "android.car.permission.CAR_UX_RESTRICTIONS_CONFIGURATION";

    /**
     * Permission necessary to listen to occupant awareness state {@link OccupantAwarenessManager}.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_READ_CAR_OCCUPANT_AWARENESS_STATE =
            "android.car.permission.READ_CAR_OCCUPANT_AWARENESS_STATE";

    /**
     * Permission necessary to access private display id.
     *
     * @hide
     */
    @SystemApi
    public static final String ACCESS_PRIVATE_DISPLAY_ID =
            "android.car.permission.ACCESS_PRIVATE_DISPLAY_ID";

    /**
     * @deprecated This permission is not used by any service.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_CAR_OCCUPANT_AWARENESS_SYSTEM =
            "android.car.permission.CONTROL_CAR_OCCUPANT_AWARENESS_SYSTEM";

    /**
     * Permissions necessary to clear diagnostic information.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_STORAGE_MONITORING =
            "android.car.permission.STORAGE_MONITORING";

    /**
     * Permission necessary to dynamically enable / disable optional car features.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_CAR_FEATURES =
            "android.car.permission.CONTROL_CAR_FEATURES";

    /**
     * Permission necessary to be car watchdog clients.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_USE_CAR_WATCHDOG =
            "android.car.permission.USE_CAR_WATCHDOG";

    /**
     * Permission necessary to monitor Car input events.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CAR_MONITOR_INPUT =
            "android.car.permission.CAR_MONITOR_INPUT";

    /**
     * Permission necessary to request CarEvsService to launch the special activity to show the
     * camera preview.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_REQUEST_CAR_EVS_ACTIVITY =
            "android.car.permission.REQUEST_CAR_EVS_ACTIVITY";

    /**
     * Permission necessary to control the special activity to show the camera preview.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_CAR_EVS_ACTIVITY =
            "android.car.permission.CONTROL_CAR_EVS_ACTIVITY";

    /**
     * Permission necessary to use the camera streams via CarEvsService.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_USE_CAR_EVS_CAMERA =
            "android.car.permission.USE_CAR_EVS_CAMERA";

    /**
     * Permission necessary to monitor the status of CarEvsService.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_MONITOR_CAR_EVS_STATUS =
            "android.car.permission.MONITOR_CAR_EVS_STATUS";

    /**
     * Permission necessary to use the CarTelemetryService.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_USE_CAR_TELEMETRY_SERVICE =
            "android.car.permission.USE_CAR_TELEMETRY_SERVICE";

    /**
     * Type of car connection: platform runs directly in car.
     *
     * @deprecated connection type constants are no longer used
     */
    @Deprecated
    public static final int CONNECTION_TYPE_EMBEDDED = 5;

    /**
     * Permission necessary to be able to render template-based UI metadata on behalf of another
     * application.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_TEMPLATE_RENDERER =
            "android.car.permission.TEMPLATE_RENDERER";

    /**
     * Permission necessary to set or retrieve car watchdog configurations.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG =
            "android.car.permission.CONTROL_CAR_WATCHDOG_CONFIG";

    /**
     * Permission necessary to collect metrics from car watchdog.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_COLLECT_CAR_WATCHDOG_METRICS =
            "android.car.permission.COLLECT_CAR_WATCHDOG_METRICS";

    /**
     * Permission necessary to fetch car CPU information.
     *
     * @hide
     */
    public static final String PERMISSION_COLLECT_CAR_CPU_INFO =
            "android.car.permission.COLLECT_CAR_CPU_INFO";

    /**
     * Permission necessary to control launching applications in Car.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_CAR_APP_LAUNCH =
            "android.car.permission.CONTROL_CAR_APP_LAUNCH";

    /**
     * Permission necessary to setting and getting thread scheduling policy and priority.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_MANAGE_THREAD_PRIORITY =
            "android.car.permission.MANAGE_THREAD_PRIORITY";

    /**
     * Permission necessary to modify occupant zone settings. Will be used in
     * {@link CarOccupantZoneManager}.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_MANAGE_OCCUPANT_ZONE =
            "android.car.permission.MANAGE_OCCUPANT_ZONE";

    /**
     * Permission necessary to use remote access.
     */
    public static final String PERMISSION_USE_REMOTE_ACCESS =
            "android.car.permission.USE_REMOTE_ACCESS";

    /**
     * Permission necessary to control remote access.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_REMOTE_ACCESS =
            "android.car.permission.CONTROL_REMOTE_ACCESS";
    /**
     * Permission necessary to control car's steering wheel.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_STEERING_WHEEL =
            "android.car.permission.CONTROL_STEERING_WHEEL";

    /**
     * Permission necessary to read ADAS settings information.
     *
     * Examples of settings include the ENABLED properties for the supported ADAS features.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_READ_ADAS_SETTINGS =
            "android.car.permission.READ_ADAS_SETTINGS";

    /**
     * Permission necessary to control ADAS settings information.
     *
     * Examples of settings include the ENABLED properties for the supported ADAS features.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_ADAS_SETTINGS =
            "android.car.permission.CONTROL_ADAS_SETTINGS";

    /**
     * Permission necessary to read ADAS states information.
     *
     * Examples include the STATE properties for the supported ADAS features.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_READ_ADAS_STATES =
            "android.car.permission.READ_ADAS_STATES";

    /**
     * Permission necessary to control ADAS states information.
     *
     * Examples include the STATE properties for the supported ADAS features.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_ADAS_STATES =
            "android.car.permission.CONTROL_ADAS_STATES";

    /**
     * Permission necessary to monitor the states of other occupant zones in the car and peer apps
     * (apps that have the same package name as the caller) installed in those zones,
     * and manage the power of those zones.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_MANAGE_REMOTE_DEVICE =
            "android.car.permission.MANAGE_REMOTE_DEVICE";

    /**
     * Permission necessary to establish connection and communicate to peer apps (apps that have
     * the same package name as the caller) installed in other occupant zones in the car.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_MANAGE_OCCUPANT_CONNECTION =
            "android.car.permission.MANAGE_OCCUPANT_CONNECTION";

    /**
     * Permission to access the mirrored Surface using the Token generated by
     * {@link CarActivityManager#createTaskMirroringToken(int)}.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_ACCESS_MIRRORRED_SURFACE =
            "android.car.permission.ACCESS_MIRRORED_SURFACE";

    /**
     * Permission to create the mirroring token for the Display.
     * See {@link CarActivityManager#createDisplayMirroringToken(int)} (int)}.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_MIRROR_DISPLAY =
            "android.car.permission.MIRROR_DISPLAY";

    /**
     * Permission necessary to read car's windshield wipers.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_READ_WINDSHIELD_WIPERS =
            "android.car.permission.READ_WINDSHIELD_WIPERS";

    /**
     * Permission necessary to control car's windshield wipers.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_CONTROL_WINDSHIELD_WIPERS =
            "android.car.permission.CONTROL_WINDSHIELD_WIPERS";

    /**
     * Permission necessary to register a {@link SystemUIProxy} that can be used by other apps to
     * manage the system ui and create task views.
     *
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_REGISTER_CAR_SYSTEM_UI_PROXY =
            "android.car.permission.REGISTER_CAR_SYSTEM_UI_PROXY";

    /**
     * Permission necessary to communicate with the car system ui for creating task views or
     * getting notified about system ui changes.
     * @hide
     */
    @SystemApi
    public static final String PERMISSION_MANAGE_CAR_SYSTEM_UI =
            "android.car.permission.MANAGE_CAR_SYSTEM_UI";

    /**
     * Permission necessary to query if a package requires launching in automotive compatibility
     * mode or not
     * @hide
     */
    @FlaggedApi(Flags.FLAG_DISPLAY_COMPATIBILITY)
    @SystemApi
    public static final String PERMISSION_QUERY_DISPLAY_COMPATIBILITY =
            "android.car.permission.QUERY_DISPLAY_COMPATIBILITY";

    /**
     * Permission necessary to read state of car airbags.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ANDROID_VIC_VEHICLE_PROPERTIES)
    @SystemApi
    public static final String PERMISSION_READ_CAR_AIRBAGS =
            "android.car.permission.READ_CAR_AIRBAGS";

    /**
     * Permission necessary to read state of seat belts.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ANDROID_VIC_VEHICLE_PROPERTIES)
    @SystemApi
    public static final String PERMISSION_READ_CAR_SEAT_BELTS =
            "android.car.permission.READ_CAR_SEAT_BELTS";

    /**
     * Permission necessary to read impact sensors information.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ANDROID_VIC_VEHICLE_PROPERTIES)
    @SystemApi
    public static final String PERMISSION_READ_IMPACT_SENSORS =
            "android.car.permission.READ_IMPACT_SENSORS";

    /**
     * Permission necessary to read valet mode
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ANDROID_VIC_VEHICLE_PROPERTIES)
    @SystemApi
    public static final String PERMISSION_READ_VALET_MODE =
            "android.car.permission.READ_VALET_MODE";

    /**
     * Permission necessary to control valet mode
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ANDROID_VIC_VEHICLE_PROPERTIES)
    @SystemApi
    public static final String PERMISSION_CONTROL_VALET_MODE =
            "android.car.permission.CONTROL_VALET_MODE";

    /**
     * Intent for connecting to the template renderer. Services that handle this intent must also
     * hold {@link #PERMISSION_TEMPLATE_RENDERER}. Applications would not bind to this service
     * directly, but instead they would use
     * <a href="https://developer.android.com/reference/com/google/android/libraries/car/app/packages">
     * Android for Cars App Library</a>.
     *
     * @hide
     */
    @SdkConstant(SdkConstantType.SERVICE_ACTION)
    public static final String CAR_TEMPLATE_HOST_RENDERER_SERVICE =
            "android.car.template.host.RendererService";

    /** @hide */
    @IntDef({CONNECTION_TYPE_EMBEDDED})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ConnectionType {}

    /**
     * @deprecated Use {@link CarMediaIntents#ACTION_MEDIA_TEMPLATE} instead.
     */
    @Deprecated
    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    public static final String CAR_INTENT_ACTION_MEDIA_TEMPLATE =
            "android.car.intent.action.MEDIA_TEMPLATE";

    /**
     * @deprecated Use {@link CarMediaIntents#EXTRA_MEDIA_COMPONENT} instead.
     */
    @Deprecated
    public static final String CAR_EXTRA_MEDIA_COMPONENT =
            "android.car.intent.extra.MEDIA_COMPONENT";

    /**
     *
     * @deprecated Use {@link #CAR_EXTRA_MEDIA_COMPONENT} instead.
     * @removed Using this for specifying MediaBrowserService was not supported since API level 29
     * and above. Apps must use {@link #CAR_EXTRA_MEDIA_COMPONENT} instead.
     */
    @Deprecated
    public static final String CAR_EXTRA_MEDIA_PACKAGE = "android.car.intent.extra.MEDIA_PACKAGE";

    /**
     * Used as a string extra field of media session to specify the service corresponding to the
     * session.
     */
    public static final String CAR_EXTRA_BROWSE_SERVICE_FOR_SESSION =
            "android.media.session.BROWSE_SERVICE";

    /**
     * Intent for being recognized as a remote task client service.
     *
     * <p>Services that use this intent must have a {@code PERMISSION_CONTROL_REMOTE_ACCESS}.
     *
     * @hide
     */
    @SystemApi
    public static final String CAR_REMOTEACCESS_REMOTE_TASK_CLIENT_SERVICE =
            "android.car.remoteaccess.RemoteTaskClientService";

    /**
     * Intent for binding the implementation of {@link
     * android.car.occupantconnection.AbstractReceiverService} in the app.
     *
     * @hide
     */
    @SdkConstant(SdkConstantType.SERVICE_ACTION)
    public static final String CAR_INTENT_ACTION_RECEIVER_SERVICE =
            "android.car.intent.action.RECEIVER_SERVICE";

    /** @hide */
    @VisibleForHiddenApiCheck
    public static final String CAR_SERVICE_INTERFACE_NAME = CommonConstants.CAR_SERVICE_INTERFACE;

    private static final String CAR_SERVICE_PACKAGE = "com.android.car";

    private static final String CAR_SERVICE_CLASS = "com.android.car.CarService";

    /**
     * Category used by navigation applications to indicate which activity should be launched on
     * the instrument cluster when such application holds
     * {@link CarAppFocusManager#APP_FOCUS_TYPE_NAVIGATION} focus.
     *
     * @hide
     */
    @VisibleForHiddenApiCheck
    public static final String CAR_CATEGORY_NAVIGATION = "android.car.cluster.NAVIGATION";

    /**
     * When an activity is launched in the cluster, it will receive {@link ClusterActivityState} in
     * the intent's extra under this key, containing instrument cluster information such as
     * unobscured area, visibility, etc.
     *
     * @hide
     */
    @SystemApi
    public static final String CAR_EXTRA_CLUSTER_ACTIVITY_STATE =
            "android.car.cluster.ClusterActivityState";


    /**
     * Callback to notify the Lifecycle of car service.
     *
     * <p>Access to car service should happen
     * after {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} call with
     * {@code ready} set {@code true}.</p>
     *
     * <p>When {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} is
     * called with ready set to false, access to car service should stop until car service is ready
     * again from {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} call
     * with {@code ready} set to {@code true}.</p>
     */
    public interface CarServiceLifecycleListener {
        /**
         * Car service has gone through status change.
         *
         * <p>This is always called in the main thread context.</p>
         *
         * @param car {@code Car} object that was originally associated with this lister from
         *            {@link #createCar(Context, Handler, long, Car.CarServiceLifecycleListener)}
         *            call.
         * @param ready when {@code true}, car service is ready and all accesses are ok
         *              Otherwise car service has crashed or killed and will be restarted
         */
        void onLifecycleChanged(@NonNull Car car, boolean ready);
    }

    /**
     * {@link #createCar(Context, Handler, long, CarServiceLifecycleListener)}'s
     * waitTimeoutMs value to use to wait forever inside the call until car service is ready.
     */
    public static final long CAR_WAIT_TIMEOUT_WAIT_FOREVER = -1;

    /**
     * {@link #createCar(Context, Handler, long, CarServiceLifecycleListener)}'s
     * waitTimeoutMs value to use to skip any waiting inside the call.
     */
    public static final long CAR_WAIT_TIMEOUT_DO_NOT_WAIT = 0;

    private static final long CAR_SERVICE_BIND_RETRY_INTERVAL_MS = 500;
    private static final long CAR_SERVICE_BIND_MAX_RETRY = 20;

    private static final long CAR_SERVICE_BINDER_POLLING_INTERVAL_MS = 50;
    private static final long CAR_SERVICE_BINDER_POLLING_MAX_RETRY = 100;

    private static final int STATE_DISCONNECTED = 0;
    private static final int STATE_CONNECTING = 1;
    private static final int STATE_CONNECTED = 2;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "STATE_", value = {
            STATE_DISCONNECTED,
            STATE_CONNECTING,
            STATE_CONNECTED,
    })
    @Target({ElementType.TYPE_USE})
    public @interface StateTypeEnum {}

    /**
     * The enabling request was successful and requires reboot to take effect.
     * @hide
     */
    @SystemApi
    public static final int FEATURE_REQUEST_SUCCESS = 0;
    /**
     * The requested feature is already enabled or disabled as requested. No need to reboot the
     * system.
     * @hide
     */
    @SystemApi
    public static final int FEATURE_REQUEST_ALREADY_IN_THE_STATE = 1;
    /**
     * The requested feature is mandatory cannot be enabled or disabled. It is always enabled.
     * @hide
     */
    @SystemApi
    public static final int FEATURE_REQUEST_MANDATORY = 2;
    /**
     * The requested feature is not available and cannot be enabled or disabled.
     * @hide
     */
    @SystemApi
    public static final int FEATURE_REQUEST_NOT_EXISTING = 3;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "FEATURE_REQUEST_", value = {
            FEATURE_REQUEST_SUCCESS,
            FEATURE_REQUEST_ALREADY_IN_THE_STATE,
            FEATURE_REQUEST_MANDATORY,
            FEATURE_REQUEST_NOT_EXISTING,
    })
    @Target({ElementType.TYPE_USE})
    public @interface FeaturerRequestEnum {}

    private final Context mContext;

    private final Exception mConstructionStack;

    private final Object mLock = new Object();

    @GuardedBy("mLock")
    private ICar mService;
    @GuardedBy("mLock")
    private boolean mServiceBound;

    @GuardedBy("mLock")
    @StateTypeEnum
    private int mConnectionState;
    @GuardedBy("mLock")
    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() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            synchronized (mLock) {
                ICar newService = ICar.Stub.asInterface(service);
                if (newService == null) {
                    Log.wtf(TAG_CAR, "null binder service", new RuntimeException());
                    return;  // should not happen.
                }
                if (mService != null && mService.asBinder().equals(newService.asBinder())) {
                    // already connected.
                    return;
                }
                mConnectionState = STATE_CONNECTED;
                mService = newService;
            }
            if (mStatusChangeCallback != null) {
                mStatusChangeCallback.onLifecycleChanged(Car.this, true);
            } else if (mServiceConnectionListenerClient != null) {
                mServiceConnectionListenerClient.onServiceConnected(name, service);
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // Car service can pick up feature changes after restart.
            mFeatures.resetCache();
            synchronized (mLock) {
                if (mConnectionState  == STATE_DISCONNECTED) {
                    // can happen when client calls disconnect before onServiceDisconnected call.
                    return;
                }
                handleCarDisconnectLocked();
            }
            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();
            }
        }
    };

    @Nullable
    private final ServiceConnection mServiceConnectionListenerClient;

    /** Can be added after ServiceManagerHelper.getService call */
    @Nullable
    private final CarServiceLifecycleListener mStatusChangeCallback;

    @GuardedBy("mLock")
    private final HashMap<String, CarManagerBase> mServiceMap = new HashMap<>();

    /** Handler for generic event dispatching. */
    private final Handler mEventHandler;

    private final Handler mMainThreadEventHandler;

    private final CarFeatures mFeatures = new CarFeatures();

    static {
        CAR_SERVICE_NAMES.put(CarSensorManager.class, SENSOR_SERVICE);
        CAR_SERVICE_NAMES.put(CarInfoManager.class, INFO_SERVICE);
        CAR_SERVICE_NAMES.put(CarAppFocusManager.class, APP_FOCUS_SERVICE);
        CAR_SERVICE_NAMES.put(CarPackageManager.class, PACKAGE_SERVICE);
        CAR_SERVICE_NAMES.put(CarAudioManager.class, AUDIO_SERVICE);
        CAR_SERVICE_NAMES.put(CarNavigationStatusManager.class, CAR_NAVIGATION_SERVICE);
        CAR_SERVICE_NAMES.put(CarOccupantZoneManager.class, CAR_OCCUPANT_ZONE_SERVICE);
        CAR_SERVICE_NAMES.put(CarUserManager.class, CAR_USER_SERVICE);
        CAR_SERVICE_NAMES.put(ExperimentalCarUserManager.class, EXPERIMENTAL_CAR_USER_SERVICE);
        CAR_SERVICE_NAMES.put(CarDevicePolicyManager.class, CAR_DEVICE_POLICY_SERVICE);
        CAR_SERVICE_NAMES.put(CarInstrumentClusterManager.class, CAR_INSTRUMENT_CLUSTER_SERVICE);
        CAR_SERVICE_NAMES.put(CarCabinManager.class, CABIN_SERVICE);
        CAR_SERVICE_NAMES.put(CarDiagnosticManager.class, DIAGNOSTIC_SERVICE);
        CAR_SERVICE_NAMES.put(CarHvacManager.class, HVAC_SERVICE);
        CAR_SERVICE_NAMES.put(CarPowerManager.class, POWER_SERVICE);
        CAR_SERVICE_NAMES.put(CarProjectionManager.class, PROJECTION_SERVICE);
        CAR_SERVICE_NAMES.put(CarPropertyManager.class, PROPERTY_SERVICE);
        CAR_SERVICE_NAMES.put(CarVendorExtensionManager.class, VENDOR_EXTENSION_SERVICE);
        CAR_SERVICE_NAMES.put(VmsClientManager.class, VEHICLE_MAP_SERVICE);
        CAR_SERVICE_NAMES.put(VmsSubscriberManager.class, VMS_SUBSCRIBER_SERVICE);
        CAR_SERVICE_NAMES.put(CarDrivingStateManager.class, CAR_DRIVING_STATE_SERVICE);
        CAR_SERVICE_NAMES.put(CarUxRestrictionsManager.class, CAR_UX_RESTRICTION_SERVICE);
        CAR_SERVICE_NAMES.put(OccupantAwarenessManager.class, OCCUPANT_AWARENESS_SERVICE);
        CAR_SERVICE_NAMES.put(CarMediaManager.class, CAR_MEDIA_SERVICE);
        CAR_SERVICE_NAMES.put(CarBugreportManager.class, CAR_BUGREPORT_SERVICE);
        CAR_SERVICE_NAMES.put(CarStorageMonitoringManager.class, STORAGE_MONITORING_SERVICE);
        CAR_SERVICE_NAMES.put(CarWatchdogManager.class, CAR_WATCHDOG_SERVICE);
        CAR_SERVICE_NAMES.put(CarPerformanceManager.class, CAR_PERFORMANCE_SERVICE);
        CAR_SERVICE_NAMES.put(CarInputManager.class, CAR_INPUT_SERVICE);
        CAR_SERVICE_NAMES.put(ClusterHomeManager.class, CLUSTER_HOME_SERVICE);
        CAR_SERVICE_NAMES.put(CarTestManager.class, TEST_SERVICE);
        CAR_SERVICE_NAMES.put(CarEvsManager.class, CAR_EVS_SERVICE);
        CAR_SERVICE_NAMES.put(CarTelemetryManager.class, CAR_TELEMETRY_SERVICE);
        CAR_SERVICE_NAMES.put(CarActivityManager.class, CAR_ACTIVITY_SERVICE);
        CAR_SERVICE_NAMES.put(CarRemoteAccessManager.class, CAR_REMOTE_ACCESS_SERVICE);
        CAR_SERVICE_NAMES.put(CarOccupantConnectionManager.class, CAR_OCCUPANT_CONNECTION_SERVICE);
        CAR_SERVICE_NAMES.put(CarRemoteDeviceManager.class, CAR_REMOTE_DEVICE_SERVICE);
        // Note: if a new entry is added here, the capacity of CAR_SERVICE_NAMES should be increased
        // as well.
    }

    /**
     * Defines the {@link CarVersion version} of the {@code Car} APIs in the device.
     *
     * <p>Starting on {@link android.os.Build.VERSION_CODES#TIRAMISU Android 13}, the {@code Car}
     * APIs can be upgraded without an OTA, so it's possible that these APIs are higher than the
     * {@link #getPlatformVersion() platform's}.
     *
     * @deprecated - use {@code android.os.Build.VERSION#SDK_INT} instead
     */
    @NonNull
    @Deprecated
    public static android.car.CarVersion getCarVersion() {
        return CAR_VERSION;
    }

    /**
     * Defines the {@link PlatformVersion version} of the standard {@code SDK} APIs in the
     * device.
     *
     * <p>Its {@link ApiVersion#getMajorVersion() major version} will be the same as
     * {@link android.os.Build.VERSION#SDK_INT} for released build but will be
     * {@link android.os.Build.VERSION_CODES#CUR_DEVELOPMENT} for platform still under development.
     *
     * @deprecated - use {@code android.os.Build.VERSION#SDK_INT} instead
     */
    @NonNull
    @Deprecated
    public static android.car.PlatformVersion getPlatformVersion() {
        return PLATFORM_VERSION;
    }

    /**
     * @deprecated - use {@code getCarApiVersion().isAtLeast(CarVersion.forMajorAndMinorVersions(
     * requiredApiVersionMajor))} instead
     */
    @Deprecated
    public static boolean isApiVersionAtLeast(int requiredApiVersionMajor) {
        return getCarVersion().isAtLeast(CarVersion.forMajorVersion(requiredApiVersionMajor));
    }

    /**
     * @deprecated - use {@code getCarVersion().isAtLeast(CarVersion.forMajorAndMinorVersions(
     * requiredApiVersionMajor, requiredApiVersionMinor)} instead
     */
    @Deprecated
    public static boolean isApiVersionAtLeast(int requiredApiVersionMajor,
            int requiredApiVersionMinor) {
        return getCarVersion()
                .isAtLeast(CarVersion.forMajorAndMinorVersions(requiredApiVersionMajor,
                        requiredApiVersionMinor));
    }

    /**
     * @deprecated - use
     * {@code getCarVersion().isAtLeast(CarVersion.forMajorVersion(requiredApiVersionMajor))
     * && getPlatformVersion().isAtLeast(PlatformVersion.forMajorVersion(minPlatformSdkInt))}
     * instead.
     */
    @Deprecated
    public static boolean isApiAndPlatformVersionAtLeast(int requiredApiVersionMajor,
            int minPlatformSdkInt) {
        return getCarVersion().isAtLeast(CarVersion.forMajorVersion(requiredApiVersionMajor))
                && getPlatformVersion()
                        .isAtLeast(PlatformVersion.forMajorVersion(minPlatformSdkInt));
    }

    /**
     * @deprecated - use {@code getCarVersion().isAtLeast(CarVersion.forMajorAndMinorVersions(
     * requiredApiVersionMajor, requiredApiVersionMinor)) && getPlatformVersion().isAtLeast(
     * PlatformVersion.forMajorVersion(minPlatformSdkInt))} instead.
     */
    @Deprecated
    public static boolean isApiAndPlatformVersionAtLeast(int requiredApiVersionMajor,
            int requiredApiVersionMinor, int minPlatformSdkInt) {
        return getCarVersion()
                .isAtLeast(CarVersion.forMajorAndMinorVersions(requiredApiVersionMajor,
                        requiredApiVersionMinor))
                && getPlatformVersion()
                        .isAtLeast(PlatformVersion.forMajorVersion(minPlatformSdkInt));
    }

    /**
     * A factory method that creates Car instance for all Car API access.
     *
     * <p>Instance created with this should be disconnected from car service by calling
     * {@link #disconnect()} before the passed {@code Context} is released.
     *
     * @param context This should not be {@code null}. If you are passing {@link ContextWrapper},
     *                make sure that its {@link ContextWrapper#getBaseContext() base context} is not
     *                {@code null} as well.
     *                Otherwise it will throw {@link java.lang.NullPointerException}.
     * @param serviceConnectionListener listener for monitoring service connection.
     * @param handler the handler on which the callback should execute, or null to execute on the
     * service's main thread. Note: the service connection listener will be always on the main
     * thread regardless of the handler given.
     * @return Car instance if system is in car environment and returns {@code null} otherwise.
     *
     * @deprecated use {@link #createCar(Context, Handler)} instead.
     */
    @Deprecated
    public static Car createCar(Context context, ServiceConnection serviceConnectionListener,
            @Nullable Handler handler) {
        assertNonNullContext(context);
        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
            Log.e(TAG_CAR, "FEATURE_AUTOMOTIVE not declared while android.car is used");
            return null;
        }
        try {
            return new Car(context, /* service= */ null , serviceConnectionListener,
                    /* statusChangeListener= */ null, handler);
        } catch (IllegalArgumentException e) {
            // Expected when car service loader is not available.
        }
        return null;
    }

    /**
     * A factory method that creates Car instance for all Car API access using main thread {@code
     * Looper}.
     *
     * <p>Instance created with this should be disconnected from car service by calling
     * {@link #disconnect()} before the passed {@code Context} is released.
     *
     * @see #createCar(Context, ServiceConnection, Handler)
     *
     * @deprecated use {@link #createCar(Context, Handler)} instead.
     */
    @Deprecated
    public static Car createCar(Context context, ServiceConnection serviceConnectionListener) {
        return createCar(context, serviceConnectionListener, null);
    }

    /**
     * Creates new {@link Car} object which connected synchronously to Car Service and ready to use.
     *
     * <p>Instance created with this should be disconnected from car service by calling
     * {@link #disconnect()} before the passed {@code Context} is released.
     *
     * @param context application's context
     *
     * @return Car object if operation succeeded, otherwise null.
     */
    @Nullable
    public static Car createCar(Context context) {
        return createCar(context, (Handler) null);
    }

    /**
     * Creates new {@link Car} object which connected synchronously to Car Service and ready to use.
     *
     * <p>Instance created with this should be disconnected from car service by calling
     * {@link #disconnect()} before the passed {@code Context} is released.
     *
     * @param context This should not be {@code null}. If you are passing {@link ContextWrapper},
     *                make sure that its {@link ContextWrapper#getBaseContext() base context} is not
     *                {@code null} as well.
     *                Otherwise it will throw {@link java.lang.NullPointerException}.
     * @param handler the handler on which the manager's callbacks will be executed, or null to
     * execute on the application's main thread.
     *
     * @return Car object if operation succeeded, otherwise null.
     */
    @Nullable
    public static Car createCar(Context context, @Nullable Handler handler) {
        assertNonNullContext(context);
        Car car = null;
        IBinder service = null;
        boolean started = false;
        int retryCount = 0;
        while (true) {
            service = ServiceManagerHelper.getService(CAR_SERVICE_BINDER_SERVICE_NAME);
            if (car == null) {
                // service can be still null. The constructor is safe for null service.
                car = new Car(context, ICar.Stub.asInterface(service),
                        null /*serviceConnectionListener*/, null /*statusChangeListener*/, handler);
            }
            if (service != null) {
                if (!started) {  // specialization for most common case.
                    // Do this to crash client when car service crashes.
                    car.startCarService();
                    return car;
                }
                break;
            }
            if (!started) {
                car.startCarService();
                started = true;
            }
            retryCount++;
            if (retryCount > CAR_SERVICE_BINDER_POLLING_MAX_RETRY) {
                Log.e(TAG_CAR, "cannot get car_service, waited for car service (ms):"
                                + CAR_SERVICE_BINDER_POLLING_INTERVAL_MS
                                * CAR_SERVICE_BINDER_POLLING_MAX_RETRY,
                        new RuntimeException());
                return null;
            }
            try {
                Thread.sleep(CAR_SERVICE_BINDER_POLLING_INTERVAL_MS);
            } catch (InterruptedException e) {
                Log.e(CarLibLog.TAG_CAR, "interrupted while waiting for car_service",
                        new RuntimeException());
                return null;
            }
        }
        // Can be accessed from mServiceConnectionListener in main thread.
        synchronized (car.mLock) {
            if (car.mService == null) {
                car.mService = ICar.Stub.asInterface(service);
                Log.w(TAG_CAR,
                        "waited for car_service (ms):"
                                + CAR_SERVICE_BINDER_POLLING_INTERVAL_MS * retryCount,
                        new RuntimeException());
            }
            car.mConnectionState = STATE_CONNECTED;
        }
        return car;
    }

    /**
     * Creates new {@link Car} object with {@link CarServiceLifecycleListener}.
     *
     * <p>Instance created with this should be disconnected from car service by calling
     * {@link #disconnect()} before the passed {@code Context} is released.
     *
     * <p> If car service is ready inside this call and if the caller is running in the main thread,
     * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} will be called
     * with ready set to be true. Otherwise,
     * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} will be called
     * from the main thread later. </p>
     *
     * <p>This call can block up to specified waitTimeoutMs to wait for car service to be ready.
     * If car service is not ready within the given time, it will return a Car instance in
     * disconnected state. Blocking main thread forever can lead into getting ANR (Application Not
     * Responding) killing from system and should not be used if the app is supposed to survive
     * across the crash / restart of car service. It can be still useful in case the app cannot do
     * anything without car service being ready. In any waiting, if the thread is getting
     * interrupted, it will return immediately.
     * </p>
     *
     * <p>Note that returned {@link Car} object is not guaranteed to be connected when there is
     * a limited timeout. Regardless of returned car being connected or not, it is recommended to
     * implement all car related initialization inside
     * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} and avoid the
     * needs to check if returned {@link Car} is connected or not from returned {@link Car}.</p>
     *
     * @param context This should not be {@code null}. If you are passing {@link ContextWrapper},
     *                make sure that its {@link ContextWrapper#getBaseContext() base context} is not
     *                {@code null} as well.
     *                Otherwise it will throw {@link java.lang.NullPointerException}.
     * @param handler dispatches all Car*Manager events to this Handler. Exception is
     *                {@link CarServiceLifecycleListener} which will be always dispatched to main
     *                thread. Passing null leads into dispatching all Car*Manager callbacks to main
     *                thread as well.
     * @param waitTimeoutMs Setting this to {@link #CAR_WAIT_TIMEOUT_DO_NOT_WAIT} will guarantee
     *                      that the API does not wait for the car service at all. Setting this to
     *                      to {@link #CAR_WAIT_TIMEOUT_WAIT_FOREVER} will block the call forever
     *                      until the car service is ready. Setting any positive value will be
     *                      interpreted as timeout value.
     */
    @NonNull
    public static Car createCar(@NonNull Context context,
            @Nullable Handler handler, long waitTimeoutMs,
            @NonNull CarServiceLifecycleListener statusChangeListener) {
        assertNonNullContext(context);
        Objects.requireNonNull(statusChangeListener);
        Car car = null;
        IBinder service = null;
        boolean started = false;
        int retryCount = 0;
        long maxRetryCount = 0;
        if (waitTimeoutMs > 0) {
            maxRetryCount = waitTimeoutMs / CAR_SERVICE_BINDER_POLLING_INTERVAL_MS;
            // at least wait once if it is positive value.
            if (maxRetryCount == 0) {
                maxRetryCount = 1;
            }
        }
        boolean isMainThread = Looper.myLooper() == Looper.getMainLooper();
        while (true) {
            service = ServiceManagerHelper.getService(CAR_SERVICE_BINDER_SERVICE_NAME);
            if (car == null) {
                // service can be still null. The constructor is safe for null service.
                car = new Car(context, ICar.Stub.asInterface(service), null, statusChangeListener,
                        handler);
            }
            if (service != null) {
                if (!started) {  // specialization for most common case : car service already ready
                    car.dispatchCarReadyToMainThread(isMainThread);
                    // Needs this for CarServiceLifecycleListener. Note that ServiceConnection
                    // will skip the callback as valid mService is set already.
                    car.startCarService();
                    return car;
                }
                // service available after starting.
                break;
            }
            if (!started) {
                car.startCarService();
                started = true;
            }
            retryCount++;
            if (waitTimeoutMs < 0 && retryCount >= CAR_SERVICE_BINDER_POLLING_MAX_RETRY
                    && retryCount % CAR_SERVICE_BINDER_POLLING_MAX_RETRY == 0) {
                // Log warning if car service is not alive even for waiting forever case.
                Log.w(TAG_CAR, "car_service not ready, waited for car service (ms):"
                                + retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
                        new RuntimeException());
            } else if (waitTimeoutMs >= 0 && retryCount > maxRetryCount) {
                if (waitTimeoutMs > 0) {
                    Log.w(TAG_CAR, "car_service not ready, waited for car service (ms):"
                                    + waitTimeoutMs,
                            new RuntimeException());
                }
                return car;
            }

            try {
                Thread.sleep(CAR_SERVICE_BINDER_POLLING_INTERVAL_MS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                Log.w(TAG_CAR, "interrupted", new RuntimeException());
                return car;
            }
        }
        // Can be accessed from mServiceConnectionListener in main thread.
        synchronized (car.mLock) {
            Log.w(TAG_CAR,
                    "waited for car_service (ms):"
                            + retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
                    new RuntimeException());
            // ServiceConnection has handled everything.
            if (car.mService != null) {
                return car;
            }
            // mService check in ServiceConnection prevents calling
            // onLifecycleChanged. So onLifecycleChanged should be called explicitly
            // but do it outside lock.
            car.mService = ICar.Stub.asInterface(service);
            car.mConnectionState = STATE_CONNECTED;
        }
        car.dispatchCarReadyToMainThread(isMainThread);
        return car;
    }

    private static void assertNonNullContext(Context context) {
        Objects.requireNonNull(context);
        if (context instanceof ContextWrapper
                && ((ContextWrapper) context).getBaseContext() == null) {
            throw new NullPointerException(
                    "ContextWrapper with null base passed as Context, forgot to set base Context?");
        }
    }

    private void dispatchCarReadyToMainThread(boolean isMainThread) {
        if (isMainThread) {
            mStatusChangeCallback.onLifecycleChanged(this, true);
        } else {
            // should dispatch to main thread.
            mMainThreadEventHandler.post(
                    () -> mStatusChangeCallback.onLifecycleChanged(this, true));
        }
    }

    private Car(Context context, @Nullable ICar service,
            @Nullable ServiceConnection serviceConnectionListener,
            @Nullable CarServiceLifecycleListener statusChangeListener,
            @Nullable Handler handler) {
        mContext = context;
        mEventHandler = determineEventHandler(handler);
        mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler);

        mService = service;
        if (service != null) {
            mConnectionState = STATE_CONNECTED;
        } else {
            mConnectionState = STATE_DISCONNECTED;
        }
        mServiceConnectionListenerClient = serviceConnectionListener;
        mStatusChangeCallback = statusChangeListener;
        // Store construction stack so that client can get help when it crashes when car service
        // crashes.
        if (serviceConnectionListener == null && statusChangeListener == null) {
            mConstructionStack = new RuntimeException();
        } else {
            mConstructionStack = null;
        }
    }

    /**
     * Car constructor when ICar binder is already available. The binder can be null.
     * @hide
     */
    public Car(Context context, @Nullable ICar service, @Nullable Handler handler) {
        this(context, service, null /*serviceConnectionListener*/, null /*statusChangeListener*/,
                handler);
    }

    private static Handler determineMainThreadEventHandler(Handler eventHandler) {
        Looper mainLooper = Looper.getMainLooper();
        return (eventHandler.getLooper() == mainLooper) ? eventHandler : new Handler(mainLooper);
    }

    private static Handler determineEventHandler(@Nullable Handler eventHandler) {
        Handler handler = eventHandler;

        if (handler == null) {
            Looper looper = Looper.getMainLooper();
            handler = new Handler(looper);
        }
        return handler;
    }

    /**
     * Connect to car service. This can be called while it is disconnected.
     * @throws IllegalStateException If connection is still on-going from previous
     *         connect call or it is already connected
     *
     * @deprecated this method is not need if this object is created via
     * {@link #createCar(Context, Handler)}.
     */
    @Deprecated
    public void connect() throws IllegalStateException {
        synchronized (mLock) {
            if (mConnectionState != STATE_DISCONNECTED) {
                throw new IllegalStateException("already connected or connecting");
            }
            mConnectionState = STATE_CONNECTING;
            startCarService();
        }
    }

    @GuardedBy("mLock")
    private void handleCarDisconnectLocked() {
        if (mConnectionState == STATE_DISCONNECTED) {
            // can happen when client calls disconnect with onServiceDisconnected already
            // called.
            return;
        }
        mEventHandler.removeCallbacks(mConnectionRetryRunnable);
        mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable);
        mConnectionRetryCount = 0;
        tearDownCarManagersLocked();
        mService = null;
        mConnectionState = STATE_DISCONNECTED;
    }

    /**
     * Disconnect from car service. This can be called while disconnected. Once disconnect is
     * called, all Car*Managers from this instance become invalid, and
     * {@link Car#getCarManager(String)} or {@link Car#getCarManager(Class<T>)} will return a
     * different instance if it is connected again.
     */
    public void disconnect() {
        synchronized (mLock) {
            handleCarDisconnectLocked();
            if (mServiceBound) {
                mContext.unbindService(mServiceConnectionListener);
                mServiceBound = false;
            }
        }
    }

    @Override
    @SuppressWarnings("GenericException")
    protected void finalize() throws Throwable {
        if (mLock == null) {
            // There's no point of trying anything - even logging - when the object state is already
            // cleared
            super.finalize();
            return;
        }
        try {
            Log.v(TAG_CAR, "Calling disconnect() on finalize()");
            disconnect();
        } finally {
            super.finalize();
        }
    }

    /**
     * Tells if it is connected to the service or not. This will return false if it is still
     * connecting.
     * @return {@code true} if service is connected
     */
    public boolean isConnected() {
        synchronized (mLock) {
            return mService != null;
        }
    }

    /**
     * Tells if this instance is already connecting to car service or not.
     * @return {@code true} if instance is connecting to a service
     */
    public boolean isConnecting() {
        synchronized (mLock) {
            return mConnectionState == STATE_CONNECTING;
        }
    }

    /** @hide */
    @VisibleForTesting
    public ServiceConnection getServiceConnectionListener() {
        return mServiceConnectionListener;
    }

    /**
     * Get car specific service manager as in {@link Context#getSystemService(String)}. Returned
     * {@link Object} should be type-casted to the desired service manager.
     *
     * <p>For example, to get the manager for sensor service,
     * <code>
     * CarSensorManager carSensorManager = (CarSensorManager) car.getCarManager(Car.SENSOR_SERVICE);
     * </code>
     *
     * @param serviceName Name of service that should be created like {@link #SENSOR_SERVICE}.
     * @return Matching service manager or null if there is no such service.
     */
    @Nullable
    public Object getCarManager(String serviceName) {
        CarManagerBase manager;
        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 = mService.getCarService(serviceName);
                    if (binder == null) {
                        Log.w(TAG_CAR, "getCarManager could not get binder for service:"
                                + serviceName);
                        return null;
                    }
                    manager = createCarManagerLocked(serviceName, binder);
                    if (manager == null) {
                        Log.w(TAG_CAR, "getCarManager could not create manager for service:"
                                        + serviceName);
                        return null;
                    }
                    mServiceMap.put(serviceName, manager);
                } catch (RemoteException e) {
                    handleRemoteExceptionFromCarService(e);
                }
            }
        }
        return manager;
    }

    /**
     * Get car specific service manager by class as in {@link Context#getSystemService(Class<T>)}.
     * Returns the desired service. No type casting is needed.
     *
     * <p>For example, to get the manager for sensor service,
     * <code>CarSensorManager carSensorManager = car.getCarManager(CarSensorManager.class);</code>
     *
     * @param serviceClass The class of the desired service.
     * @return Matching service manager or {@code null} if there is no such service.
     */
    @Nullable
    public <T> T getCarManager(@NonNull Class<T> serviceClass) {
        String serviceName = CAR_SERVICE_NAMES.get(serviceClass);
        return serviceName != null ? (T) getCarManager(serviceName) : null;
    }

    /**
     * @return the type of currently connected car.
     *
     * @deprecated connection type will be always {@link #CONNECTION_TYPE_EMBEDDED}
     */
    @ConnectionType
    @Deprecated
    public int getCarConnectionType() {
        return CONNECTION_TYPE_EMBEDDED;
    }

    /**
     * Checks if {@code featureName} is enabled in this car.
     *
     * <p>For optional features, this can return false if the car cannot support it. Optional
     * features should be used only when they are supported.</p>
     *
     * <p>For mandatory features, this will always return true.
     */
    public boolean isFeatureEnabled(@NonNull String featureName) {
        ICar service;
        synchronized (mLock) {
            if (mService == null) {
                return false;
            }
            service = mService;
        }
        return mFeatures.isFeatureEnabled(service, featureName);
    }

    /**
     * Enables the requested car feature. It becomes no-op if the feature is already enabled. The
     * change take effects after reboot.
     *
     * @return true if the feature is enabled or was enabled before.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
    @FeaturerRequestEnum
    public int enableFeature(@NonNull String featureName) {
        ICar service;
        synchronized (mLock) {
            if (mService == null) {
                return FEATURE_REQUEST_NOT_EXISTING;
            }
            service = mService;
        }
        try {
            return service.enableFeature(featureName);
        } catch (RemoteException e) {
            return handleRemoteExceptionFromCarService(e, FEATURE_REQUEST_NOT_EXISTING);
        }
    }

    /**
     * Disables the requested car feature. It becomes no-op if the feature is already disabled. The
     * change take effects after reboot.
     *
     * @return true if the request succeeds or if it was already disabled.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
    @FeaturerRequestEnum
    public int disableFeature(@NonNull String featureName) {
        ICar service;
        synchronized (mLock) {
            if (mService == null) {
                return FEATURE_REQUEST_NOT_EXISTING;
            }
            service = mService;
        }
        try {
            return service.disableFeature(featureName);
        } catch (RemoteException e) {
            return handleRemoteExceptionFromCarService(e, FEATURE_REQUEST_NOT_EXISTING);
        }
    }

    /**
     * Returns all =enabled features at the moment including mandatory, optional, and
     * experimental features.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
    @NonNull public List<String> getAllEnabledFeatures() {
        ICar service;
        synchronized (mLock) {
            if (mService == null) {
                return Collections.EMPTY_LIST;
            }
            service = mService;
        }
        try {
            return service.getAllEnabledFeatures();
        } catch (RemoteException e) {
            return handleRemoteExceptionFromCarService(e, Collections.EMPTY_LIST);
        }
    }

    /**
     * Returns the list of disabled features which are not effective yet. Those features will be
     * disabled when system restarts later.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
    @NonNull public List<String> getAllPendingDisabledFeatures() {
        ICar service;
        synchronized (mLock) {
            if (mService == null) {
                return Collections.EMPTY_LIST;
            }
            service = mService;
        }
        try {
            return service.getAllPendingDisabledFeatures();
        } catch (RemoteException e) {
            return handleRemoteExceptionFromCarService(e, Collections.EMPTY_LIST);
        }
    }

    /**
     * Returns the list of enabled features which are not effective yet. Those features will be
     * enabled when system restarts later.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
    @NonNull public List<String> getAllPendingEnabledFeatures() {
        ICar service;
        synchronized (mLock) {
            if (mService == null) {
                return Collections.EMPTY_LIST;
            }
            service = mService;
        }
        try {
            return service.getAllPendingEnabledFeatures();
        } catch (RemoteException e) {
            return handleRemoteExceptionFromCarService(e, Collections.EMPTY_LIST);
        }
    }

    /** @hide */
    @VisibleForHiddenApiCheck
    public Context getContext() {
        return mContext;
    }

    /** @hide */
    @VisibleForTesting
    public Handler getEventHandler() {
        return mEventHandler;
    }

    /** @hide */
    @VisibleForTesting
    public <T> T handleRemoteExceptionFromCarService(RemoteException e, T returnValue) {
        handleRemoteExceptionFromCarService(e);
        return returnValue;
    }

    /** @hide */
    @VisibleForHiddenApiCheck
    public void handleRemoteExceptionFromCarService(RemoteException e) {
        if (e instanceof TransactionTooLargeException) {
            Log.w(TAG_CAR, "Car service threw TransactionTooLargeException", e);
            throw new CarTransactionException(e, "Car service threw TransactionTooLargeException");
        } else {
            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, created "
                                + "from " + mConstructionStack);
                activity.finish();
            }
            return;
        } else if (mContext instanceof Service) {
            Service service = (Service) mContext;
            killClient(service.getPackageName() + "," + service.getClass().getSimpleName());
        } else {
            killClient(/* clientInfo= */ null);
        }
    }

    private void killClient(@Nullable String clientInfo) {
        Log.w(TAG_CAR, "**Car service has crashed. Client(" + clientInfo + ") is not handling it."
                        + " Client should use Car.createCar(..., CarServiceLifecycleListener, .."
                        + ".) to handle it properly. Check printed callstack to check where other "
                        + "version of Car.createCar() was called. Killing the client process**",
                mConstructionStack);
        Process.killProcess(Process.myPid());
    }

    /** @hide */
    @VisibleForHiddenApiCheck
    public static <T> T handleRemoteExceptionFromCarService(Service service, RemoteException e,
            T returnValue) {
        handleRemoteExceptionFromCarService(service, e);
        return returnValue;
    }

    /** @hide */
    @VisibleForHiddenApiCheck
    public static  void handleRemoteExceptionFromCarService(Service service, RemoteException e) {
        if (e instanceof TransactionTooLargeException) {
            Log.w(TAG_CAR, "Car service threw TransactionTooLargeException, client:"
                    + service.getPackageName() + ","
                    + service.getClass().getSimpleName(), e);
            throw new CarTransactionException(e, "Car service threw TransactionTooLargeException, "
                + "client: %s, %s", service.getPackageName(), service.getClass().getSimpleName());
        } else {
            Log.w(TAG_CAR, "Car service has crashed, client:"
                    + service.getPackageName() + ","
                    + service.getClass().getSimpleName(), e);
            service.stopSelf();
        }
    }

    @Nullable
    private CarManagerBase createCarManagerLocked(String serviceName, IBinder binder) {
        CarManagerBase manager = null;
        switch (serviceName) {
            case AUDIO_SERVICE:
                manager = new CarAudioManager(this, binder);
                break;
            case SENSOR_SERVICE:
                manager = new CarSensorManager(this, binder);
                break;
            case INFO_SERVICE:
                manager = new CarInfoManager(this, binder);
                break;
            case APP_FOCUS_SERVICE:
                manager = new CarAppFocusManager(this, binder);
                break;
            case PACKAGE_SERVICE:
                manager = new CarPackageManager(this, binder);
                break;
            case CAR_OCCUPANT_ZONE_SERVICE:
                manager = new CarOccupantZoneManager(this, binder);
                break;
            case CAR_NAVIGATION_SERVICE:
                manager = new CarNavigationStatusManager(this, binder);
                break;
            case CABIN_SERVICE:
                manager = new CarCabinManager(this, binder);
                break;
            case DIAGNOSTIC_SERVICE:
                manager = new CarDiagnosticManager(this, binder);
                break;
            case HVAC_SERVICE:
                manager = new CarHvacManager(this, binder);
                break;
            case POWER_SERVICE:
                manager = new CarPowerManager(this, binder);
                break;
            case PROJECTION_SERVICE:
                manager = new CarProjectionManager(this, binder);
                break;
            case PROPERTY_SERVICE:
                manager = new CarPropertyManager(this, ICarProperty.Stub.asInterface(binder));
                break;
            case VENDOR_EXTENSION_SERVICE:
                manager = new CarVendorExtensionManager(this, binder);
                break;
            case CAR_INSTRUMENT_CLUSTER_SERVICE:
                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 CarTestManager(this, binder);
                break;
            case VEHICLE_MAP_SERVICE:
                manager = new VmsClientManager(this, binder);
                break;
            case VMS_SUBSCRIBER_SERVICE:
                manager = VmsSubscriberManager.wrap(this,
                        (VmsClientManager) getCarManager(VEHICLE_MAP_SERVICE));
                break;
            case STORAGE_MONITORING_SERVICE:
                manager = new CarStorageMonitoringManager(this, binder);
                break;
            case CAR_DRIVING_STATE_SERVICE:
                manager = new CarDrivingStateManager(this, binder);
                break;
            case CAR_UX_RESTRICTION_SERVICE:
                manager = new CarUxRestrictionsManager(this, binder);
                break;
            case OCCUPANT_AWARENESS_SERVICE:
                manager = new OccupantAwarenessManager(this, binder);
                break;
            case CAR_MEDIA_SERVICE:
                manager = new CarMediaManager(this, binder);
                break;
            case CAR_BUGREPORT_SERVICE:
                manager = new CarBugreportManager(this, binder);
                break;
            case CAR_USER_SERVICE:
                manager = new CarUserManager(this, binder);
                break;
            case EXPERIMENTAL_CAR_USER_SERVICE:
                manager = new ExperimentalCarUserManager(this, binder);
                break;
            case CAR_WATCHDOG_SERVICE:
                manager = new CarWatchdogManager(this, binder);
                break;
            case CAR_INPUT_SERVICE:
                manager = new CarInputManager(this, binder);
                break;
            case CAR_DEVICE_POLICY_SERVICE:
                manager = new CarDevicePolicyManager(this, binder);
                break;
            case CLUSTER_HOME_SERVICE:
                manager = new ClusterHomeManager(this, binder);
                break;
            case CAR_EVS_SERVICE:
                manager = new CarEvsManager(this, binder);
                break;
            case CAR_TELEMETRY_SERVICE:
                manager = new CarTelemetryManager(this, binder);
                break;
            case CAR_ACTIVITY_SERVICE:
                manager = new CarActivityManager(this, binder);
                break;
            case CAR_PERFORMANCE_SERVICE:
                manager = new CarPerformanceManager(this, binder);
                break;
            case CAR_REMOTE_ACCESS_SERVICE:
                manager = new CarRemoteAccessManager(this, binder);
                break;
            case CAR_OCCUPANT_CONNECTION_SERVICE:
                manager = new CarOccupantConnectionManager(this, binder);
                break;
            case CAR_REMOTE_DEVICE_SERVICE:
                manager = new CarRemoteDeviceManager(this, binder);
                break;
            default:
                // Experimental or non-existing
                String className = null;
                try {
                    synchronized (mLock) {
                        className = mService.getCarManagerClassForFeature(serviceName);
                    }
                } catch (RemoteException e) {
                    handleRemoteExceptionFromCarService(e);
                    return null;
                }
                if (className == null) {
                    Log.e(TAG_CAR, "Cannot construct CarManager for service:" + serviceName
                            + " : no class defined");
                    return null;
                }
                manager = constructCarManager(className, binder);
                break;
        }
        return manager;
    }

    private CarManagerBase constructCarManager(String className, IBinder binder) {
        try {
            // Should use class loader for the Context as class loader for car api does not
            // see the class.
            ClassLoader loader = mContext.getClassLoader();
            Class managerClass = loader.loadClass(className);
            Constructor constructor = managerClass.getConstructor(Car.class, IBinder.class);
            CarManagerBase manager = (CarManagerBase) constructor.newInstance(this, binder);
            return manager;
        } catch (ClassNotFoundException | IllegalAccessException | NoSuchMethodException
                | InstantiationException | InvocationTargetException e) {
            Log.e(TAG_CAR, "Cannot construct CarManager, class:" + className, e);
            return null;
        }
    }

    private void startCarService() {
        Intent intent = new Intent();
        intent.setPackage(CAR_SERVICE_PACKAGE);
        intent.setAction(Car.CAR_SERVICE_INTERFACE_NAME);
        boolean bound = mContext.bindService(intent, mServiceConnectionListener,
                Context.BIND_AUTO_CREATE);
        synchronized (mLock) {
            if (!bound) {
                mConnectionRetryCount++;
                if (mConnectionRetryCount > CAR_SERVICE_BIND_MAX_RETRY) {
                    Log.w(TAG_CAR, "cannot bind to car service after max retry");
                    mMainThreadEventHandler.post(mConnectionRetryFailedRunnable);
                } else {
                    mEventHandler.postDelayed(mConnectionRetryRunnable,
                            CAR_SERVICE_BIND_RETRY_INTERVAL_MS);
                }
            } else {
                mEventHandler.removeCallbacks(mConnectionRetryRunnable);
                mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable);
                mConnectionRetryCount = 0;
                mServiceBound = true;
            }
        }
    }

    @GuardedBy("mLock")
    private void tearDownCarManagersLocked() {
        // All disconnected handling should be only doing its internal cleanup.
        for (CarManagerBase manager : mServiceMap.values()) {
            manager.onCarDisconnected();
        }
        mServiceMap.clear();
    }
}
