Merge "Post-O: skeleton for product configuration support in CarInfoManager"
diff --git a/car-lib/Android.mk b/car-lib/Android.mk
index d1581da..7ef3cbe 100644
--- a/car-lib/Android.mk
+++ b/car-lib/Android.mk
@@ -24,6 +24,12 @@
 LOCAL_MODULE := android.car
 LOCAL_MODULE_TAGS := optional
 
+ifneq ($(TARGET_USES_CAR_FUTURE_FEATURES),true)
+#TODO need a tool to generate proguard rule to drop all items under @FutureFeature
+#LOCAL_PROGUARD_ENABLED := custom
+#LOCAL_PROGUARD_FLAG_FILES := proguard_drop_future.flags
+endif
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-Iaidl-files-under, src)
 
 ifeq ($(EMMA_INSTRUMENT_FRAMEWORK),true)
diff --git a/car-lib/src/android/car/CarInfoManager.java b/car-lib/src/android/car/CarInfoManager.java
index b70f6c9..b73e879 100644
--- a/car-lib/src/android/car/CarInfoManager.java
+++ b/car-lib/src/android/car/CarInfoManager.java
@@ -17,6 +17,7 @@
 package android.car;
 
 import android.annotation.Nullable;
+import android.car.annotation.FutureFeature;
 import android.car.annotation.ValueTypeDef;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -63,6 +64,14 @@
     @ValueTypeDef(type = String.class)
     public static final String BASIC_INFO_KEY_VEHICLE_ID = "android.car.vehicle-id";
 
+    /**
+     * Key for product configuration info.
+     * @FutureFeature Cannot drop due to usage in non-flag protected place.
+     * @hide
+     */
+    @ValueTypeDef(type = String.class)
+    public static final String INFO_KEY_PRODUCT_CONFIGURATION = "android.car.product-config";
+
     /* TODO bug: 32059999
     //@ValueTypeDef(type = Integer.class)
     //public static final String KEY_DRIVER_POSITION = "driver-position";
@@ -121,6 +130,26 @@
     }
 
     /**
+     * Get product configuration string. Contents of this string is product specific but it should
+     * be composed of key-value pairs with the format of:
+     *   key1=value1;key2=value2;...
+     * @return null if such information is not available in this car.
+     * @throws CarNotConnectedException
+     * @hide
+     */
+    @FutureFeature
+    public @Nullable String getProductConfiguration() throws CarNotConnectedException {
+        try {
+            return mService.getStringInfo(INFO_KEY_PRODUCT_CONFIGURATION);
+        } catch (IllegalStateException e) {
+            CarApiUtil.checkCarNotConnectedExceptionFromCarService(e);
+        } catch (RemoteException e) {
+            throw new CarNotConnectedException(e);
+        }
+        return null;
+    }
+
+    /**
      * Get {@link android.os.Bundle} containing basic car information. Check
      * {@link #BASIC_INFO_KEY_MANUFACTURER}, {@link #BASIC_INFO_KEY_MODEL},
      * {@link #BASIC_INFO_KEY_MODEL_YEAR}, and {@link #BASIC_INFO_KEY_VEHICLE_ID} for supported
diff --git a/car-lib/src/android/car/ICarInfo.aidl b/car-lib/src/android/car/ICarInfo.aidl
index 0267f4f..b43e611 100644
--- a/car-lib/src/android/car/ICarInfo.aidl
+++ b/car-lib/src/android/car/ICarInfo.aidl
@@ -20,5 +20,6 @@
 
 /** @hide */
 interface ICarInfo {
-	Bundle getBasicInfo() = 0;
+    Bundle getBasicInfo() = 0;
+    String getStringInfo(in String key) = 1;
 }
diff --git a/car-lib/src/android/car/internal/FeatureUtil.java b/car-lib/src/android/car/internal/FeatureUtil.java
new file mode 100644
index 0000000..bf47ed7
--- /dev/null
+++ b/car-lib/src/android/car/internal/FeatureUtil.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 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.internal;
+
+/**
+ * Internal utility for checking feature
+ * @hide
+ */
+public class FeatureUtil {
+
+    public static void assertFeature(boolean featureFlag) {
+        if (!featureFlag) {
+            throw new IllegalStateException("Feature not enabled");
+        }
+    }
+}
diff --git a/service/src/com/android/car/CarInfoService.java b/service/src/com/android/car/CarInfoService.java
index 9715325..f18f955 100644
--- a/service/src/com/android/car/CarInfoService.java
+++ b/service/src/com/android/car/CarInfoService.java
@@ -17,6 +17,7 @@
 
 import android.car.CarInfoManager;
 import android.car.ICarInfo;
+import android.car.internal.FeatureUtil;
 import android.content.Context;
 import android.os.Bundle;
 import android.provider.Settings;
@@ -41,6 +42,25 @@
     }
 
     @Override
+    public String getStringInfo(String key) {
+        switch (key) {
+            case CarInfoManager.INFO_KEY_PRODUCT_CONFIGURATION:
+                FeatureUtil.assertFeature(
+                        FeatureConfiguration.ENABLE_PRODUCT_CONFIGURATION_INFO);
+                // still protect with if-feature code. code under if can be dropped by
+                // proguard if necessary.
+                if (FeatureConfiguration.ENABLE_PRODUCT_CONFIGURATION_INFO) {
+                    //TODO get it from HAL layer
+                    return null;
+                }
+                break;
+            default: // just throw exception
+                break;
+        }
+        throw new IllegalArgumentException("Unsupported key:" + key);
+    }
+
+    @Override
     public void init() {
         Bundle info = mInfoHal.getBasicInfo();
         // do not update ID immediately even if user clears it.
diff --git a/service/src_feature_current/com/android/car/FeatureConfiguration.java b/service/src_feature_current/com/android/car/FeatureConfiguration.java
index 947ddc9..309bf06 100644
--- a/service/src_feature_current/com/android/car/FeatureConfiguration.java
+++ b/service/src_feature_current/com/android/car/FeatureConfiguration.java
@@ -21,5 +21,7 @@
 public class FeatureConfiguration {
     /** Disable future feature by default. */
     public static final boolean DEFAULT = false;
+    /** product configuration in CarInfoManager */
+    public static final boolean ENABLE_PRODUCT_CONFIGURATION_INFO = DEFAULT;
 
 }
diff --git a/service/src_feature_future/com/android/car/FeatureConfiguration.java b/service/src_feature_future/com/android/car/FeatureConfiguration.java
index 7d11059..de6d6b1 100644
--- a/service/src_feature_future/com/android/car/FeatureConfiguration.java
+++ b/service/src_feature_future/com/android/car/FeatureConfiguration.java
@@ -21,4 +21,6 @@
 public class FeatureConfiguration {
     /** Enable future feature by default. */
     public static final boolean DEFAULT = true;
+    /** product configuration in CarInfoManager */
+    public static final boolean ENABLE_PRODUCT_CONFIGURATION_INFO = DEFAULT;
 }