1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.car;
18
19import android.annotation.Nullable;
20import android.car.annotation.FutureFeature;
21import android.car.annotation.ValueTypeDef;
22import android.os.Bundle;
23import android.os.IBinder;
24import android.os.RemoteException;
25
26
27import com.android.internal.annotations.GuardedBy;
28
29import java.lang.annotation.Retention;
30import java.lang.annotation.RetentionPolicy;
31
32
33/**
34 * Utility to retrieve various static information from car. Each data are grouped as {@link Bundle}
35 * and relevant data can be checked from {@link Bundle} using pre-specified keys.
36 */
37public final class CarInfoManager implements CarManagerBase {
38
39    /**
40     * Key for manufacturer of the car. Passed in basic info Bundle.
41     * @hide
42     */
43    @ValueTypeDef(type = String.class)
44    public static final String BASIC_INFO_KEY_MANUFACTURER = "android.car.manufacturer";
45    /**
46     * Key for model name of the car. This information may not necessarily allow distinguishing
47     * different car models as the same name may be used for different cars depending on
48     * manufacturers. Passed in basic info Bundle.
49     * @hide
50     */
51    @ValueTypeDef(type = String.class)
52    public static final String BASIC_INFO_KEY_MODEL = "android.car.model";
53    /**
54     * Key for model year of the car in AC. Passed in basic info Bundle.
55     * @hide
56     */
57    @ValueTypeDef(type = Integer.class)
58    public static final String BASIC_INFO_KEY_MODEL_YEAR = "android.car.model-year";
59    /**
60     * Key for unique identifier for the car. This is not VIN, and id is persistent until user
61     * resets it. Passed in basic info Bundle.
62     * @hide
63     */
64    @ValueTypeDef(type = String.class)
65    public static final String BASIC_INFO_KEY_VEHICLE_ID = "android.car.vehicle-id";
66
67    /**
68     * Key for product configuration info.
69     * @FutureFeature Cannot drop due to usage in non-flag protected place.
70     * @hide
71     */
72    @ValueTypeDef(type = String.class)
73    public static final String INFO_KEY_PRODUCT_CONFIGURATION = "android.car.product-config";
74
75    /* TODO bug: 32059999
76    //@ValueTypeDef(type = Integer.class)
77    //public static final String KEY_DRIVER_POSITION = "driver-position";
78
79    //@ValueTypeDef(type = int[].class)
80    //public static final String KEY_SEAT_CONFIGURATION = "seat-configuration";
81
82    //@ValueTypeDef(type = Integer.class)
83    //public static final String KEY_WINDOW_CONFIGURATION = "window-configuration";
84
85    //MT, AT, CVT, ...
86    //@ValueTypeDef(type = Integer.class)
87    //public static final String KEY_TRANSMISSION_TYPE = "transmission-type";
88
89    // add: transmission gear available selection, gear available steps
90    //          drive wheel: FWD, RWD, AWD, 4WD */
91
92    private final ICarInfo mService;
93
94    @GuardedBy("this")
95    private Bundle mBasicInfo;
96
97    /**
98     * Return manufacturer of the car.
99     * @return null if information is not available.
100     */
101    public @android.annotation.Nullable String getManufacturer() throws CarNotConnectedException {
102        return getBasicInfo().getString(BASIC_INFO_KEY_MANUFACTURER);
103    }
104
105    /**
106     * Return model name of the car. This information may not necessarily allow distinguishing
107     * different car models as the same name may be used for different cars depending on
108     * manufacturers.
109     * @return null if information is not available.
110     */
111    public @Nullable String getModel() throws CarNotConnectedException {
112        return getBasicInfo().getString(BASIC_INFO_KEY_MODEL);
113    }
114
115    /**
116     * Return model year of the car in AC.
117     * @return null if information is not available.
118     */
119    public @Nullable String getModelYear() throws CarNotConnectedException {
120        return getBasicInfo().getString(BASIC_INFO_KEY_MODEL_YEAR);
121    }
122
123    /**
124     * Return unique identifier for the car. This is not VIN, and id is persistent until user
125     * resets it. This ID is guaranteed to be always available.
126     * @return vehicle id
127     */
128    public String getVehicleId() throws CarNotConnectedException {
129        return getBasicInfo().getString(BASIC_INFO_KEY_VEHICLE_ID);
130    }
131
132    /**
133     * Get product configuration string. Contents of this string is product specific but it should
134     * be composed of key-value pairs with the format of:
135     *   key1=value1;key2=value2;...
136     * @return null if such information is not available in this car.
137     * @throws CarNotConnectedException
138     * @hide
139     */
140    @FutureFeature
141    public @Nullable String getProductConfiguration() throws CarNotConnectedException {
142        try {
143            return mService.getStringInfo(INFO_KEY_PRODUCT_CONFIGURATION);
144        } catch (IllegalStateException e) {
145            CarApiUtil.checkCarNotConnectedExceptionFromCarService(e);
146        } catch (RemoteException e) {
147            throw new CarNotConnectedException(e);
148        }
149        return null;
150    }
151
152    /**
153     * Get {@link android.os.Bundle} containing basic car information. Check
154     * {@link #BASIC_INFO_KEY_MANUFACTURER}, {@link #BASIC_INFO_KEY_MODEL},
155     * {@link #BASIC_INFO_KEY_MODEL_YEAR}, and {@link #BASIC_INFO_KEY_VEHICLE_ID} for supported
156     * keys in the {@link android.os.Bundle}.
157     * @return {@link android.os.Bundle} containing basic car info.
158     * @throws CarNotConnectedException
159     */
160    private synchronized Bundle getBasicInfo() throws CarNotConnectedException {
161        if (mBasicInfo != null) {
162            return mBasicInfo;
163        }
164        try {
165            mBasicInfo = mService.getBasicInfo();
166        } catch (IllegalStateException e) {
167            CarApiUtil.checkCarNotConnectedExceptionFromCarService(e);
168        } catch (RemoteException e) {
169            throw new CarNotConnectedException(e);
170        }
171        return mBasicInfo;
172    }
173
174    /** @hide */
175    CarInfoManager(IBinder service) {
176        mService = ICarInfo.Stub.asInterface(service);
177    }
178
179    /** @hide */
180    @Override
181    public void onCarDisconnected() {
182        synchronized (this) {
183            mBasicInfo = null;
184        }
185    }
186}
187