Merge "VTS tests should be static" into pi-dev
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index faa1adc..23f9b77 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -42,6 +42,9 @@
 };
 
 /**
+ * Vehicle Areas
+ * Used to construct property IDs in the VehicleProperty enum.
+ *
  * Some properties may be associated with particular vehicle areas. For
  * example, VehicleProperty:DOOR_LOCK property must be associated with
  * particular door, thus this property must be marked with
@@ -50,8 +53,34 @@
  * Other properties may not be associated with particular vehicle area,
  * these kind of properties must have VehicleArea:GLOBAL flag.
  *
- * Used to create property ID in VehicleProperty enum.
- */
+ * [Definition] Area: An area represents a unique element of an AreaType.
+ *   For instance, if AreaType is WINDOW, then an area may be FRONT_WINDSHIELD.
+ *
+ * [Definition] AreaID: An AreaID is a combination of one or more areas,
+ *   and is represented using a bitmask of Area enums. Different AreaTypes may
+ *   not be mixed in a single AreaID. For instance, a window area cannot be
+ *   combined with a seat area in an AreaID.
+ *
+ * Rules for mapping a zoned property to AreaIDs:
+ *  - A property must be mapped to an array of AreaIDs that are impacted when
+ *    the property value changes.
+ *  - Each element in the array must represent an AreaID, in which, the
+ *    property value can only be changed together in all the areas within
+ *    an AreaID and never independently. That is, when the property value
+ *    changes in one of the areas in an AreaID in the array, then it must
+ *    automatically change in all other areas in the AreaID.
+ *  - The property value must be independently controllable in any two
+ *    different AreaIDs in the array.
+ *  - An area must only appear once in the array of AreaIDs. That is, an
+ *    area must only be part of a single AreaID in the array.
+ *
+ * [Definition] Global Property: A property that applies to the entire car
+ *   and is not associated with a specific area. For example, FUEL_LEVEL,
+ *   HVAC_STEERING_WHEEL_HEAT.
+ *
+ * Rules for mapping a global property to AreaIDs:
+ *  - A global property must not be mapped to AreaIDs.
+*/
 enum VehicleArea : int32_t {
     GLOBAL      = 0x01000000,
     /** WINDOW maps to enum VehicleAreaWindow */
@@ -331,16 +360,16 @@
     /**
      * Reports wheel ticks
      *
-     * The first four elements represent ticks for individual wheels in the
+     * The first element in the vector is a reset count.  A reset indicates
+     * previous tick counts are not comparable with this and future ones.  Some
+     * sort of discontinuity in tick counting has occurred.
+     *
+     * The next four elements represent ticks for individual wheels in the
      * following order: front left, front right, rear right, rear left.  All
      * tick counts are cumulative.  Tick counts increment when the vehicle
      * moves forward, and decrement when vehicles moves in reverse.  The ticks
      * should be reset to 0 when the vehicle is started by the user.
      *
-     * The next element in the vector is a reset count.  A reset indicates
-     * previous tick counts are not comparable with this and future ones.  Some
-     * sort of discontinuity in tick counting has occurred.
-     *
      *  int64Values[0] = reset count
      *  int64Values[1] = front left ticks
      *  int64Values[2] = front right ticks
@@ -489,6 +518,12 @@
      *
      * This is the gear selected by the user.
      *
+     * Values in the config data must represent the list of supported gears
+     * for this vehicle.  For example, config data for an automatic transmission
+     * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_DRIVE,
+     * GEAR_1, GEAR_2,...} and for manual transmission the list must be
+     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}
+     *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ
      * @data_enum VehicleGear
@@ -500,8 +535,17 @@
         | VehicleArea:GLOBAL),
 
     /**
-     * Current gear. In non-manual case, selected gear does not necessarily
-     * match the current gear.
+     * Current gear. In non-manual case, selected gear may not
+     * match the current gear. For example, if the selected gear is GEAR_DRIVE,
+     * the current gear will be one of GEAR_1, GEAR_2 etc, which reflects
+     * the actual gear the transmission is currently running in.
+     *
+     * Values in the config data must represent the list of supported gears
+     * for this vehicle.  For example, config data for an automatic transmission
+     * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...}
+     * and for manual transmission the list must be
+     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the
+     * same as that of the supported gears reported in GEAR_SELECTION.
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ
@@ -625,6 +669,41 @@
         | VehiclePropertyType:BOOLEAN
         | VehicleArea:GLOBAL),
 
+    /*
+     * HVAC Properties
+     *
+     * Additional rules for mapping a zoned HVAC property to AreaIDs:
+     *  - Every seat in VehicleAreaSeat that is available in the car, must be
+     *    part of an AreaID in the AreaID array.
+     *
+     * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
+     *  temperature control units -- driver side and passenger side.
+     *   - A valid mapping set of AreaIDs for HVAC_TEMPERATURE_SET would be a
+     *     two element array:
+     *      - ROW_1_LEFT  | ROW_2_LEFT
+     *      - ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT
+     *   - An alternative mapping for the same hardware configuration would be:
+     *      - ROW_1_LEFT  | ROW_2_CENTER | ROW_2_LEFT
+     *      - ROW_1_RIGHT | ROW_2_RIGHT
+     *  The temperature controllers are assigned to the seats which they
+     *  "most influence", but every seat must be included exactly once. The
+     *  assignment of the center rear seat to the left or right AreaID may seem
+     *  arbitrary, but the inclusion of every seat in exactly one AreaID ensures
+     *  that the seats in the car are all expressed and that a "reasonable" way
+     *  to affect each seat is available.
+     *
+     * Example 2: A car has three seat rows with two seats in the front row (ROW_1_LEFT,
+     *  ROW_1_RIGHT) and three seats in the second (ROW_2_LEFT, ROW_2_CENTER,
+     *  ROW_2_RIGHT) and third rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). There
+     *  are three temperature control units -- driver side, passenger side, and rear.
+     *   - A reasonable way to map HVAC_TEMPERATURE_SET to AreaIDs is a three
+     *     element array:
+     *     - ROW_1_LEFT
+     *     - ROW_1_RIGHT
+     *     - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
+     */
+
     /**
      * Fan speed setting
      *
@@ -754,22 +833,34 @@
         | VehicleArea:SEAT),
 
     /**
-     * Enable temperature coupling between zones.
+     * Enable temperature coupling between areas.
      *
-     * The areaId for this property must include the zones that are coupled
-     * together.  Typically, the front two zones (ROW_1_LEFT and ROW_1_RIGHT)
-     * are coupled together when this property is enabled.  Thus, the areaId
-     * shall be (ROW_1_LEFT | ROW_1_RIGHT).  When the property is enabled, the
-     * ECU may synchronize the temperature for the affected zones.  Any
-     * parameters modified as a side effect of turning on/off the DUAL_ON
-     * parameter shall generate onPropertyEvent() callbacks to the VHAL.  In
-     * addition, if setting a temperature (i.e. driver's temp) changes another
-     * temperature (i.e. front passenger's temp), then the appropriate
+     * The AreaIDs for HVAC_DUAL_ON property shall contain a combination of
+     * HVAC_TEMPERATURE_SET AreaIDs that can be coupled together. If
+     * HVAC_TEMPERATURE_SET is mapped to AreaIDs [a_1, a_2, ..., a_n], and if
+     * HVAC_DUAL_ON can be enabled to couple a_i and a_j, then HVAC_DUAL_ON
+     * property must be mapped to [a_i | a_j]. Further, if a_k and a_l can also
+     * be coupled together separately then HVAC_DUAL_ON must be mapped to
+     * [a_i | a_j, a_k | a_l].
+     *
+     * Example: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
+     *  temperature control units -- driver side and passenger side -- which can
+     *  be optionally synchronized. This may be expressed in the AreaIDs this way:
+     *  - HVAC_TEMPERATURE_SET->[ROW_1_LEFT | ROW_2_LEFT, ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
+     *  - HVAC_DUAL_ON->[ROW_1_LEFT | ROW_2_LEFT | ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
+     *
+     * When the property is enabled, the ECU must synchronize the temperature
+     * for the affected areas. Any parameters modified as a side effect
+     * of turning on/off the DUAL_ON parameter shall generate
+     * onPropertyEvent() callbacks to the VHAL. In addition, if setting
+     * a temperature (i.e. driver's temperature) changes another temperature
+     * (i.e. front passenger's temperature), then the appropriate
      * onPropertyEvent() callbacks must be generated.  If a user changes a
      * temperature that breaks the coupling (e.g. setting the passenger
      * temperature independently) then the VHAL must send the appropriate
      * onPropertyEvent() callbacks (i.e. HVAC_DUAL_ON = false,
-     * HVAC_TEMPERATURE_SET[zone] = xxx, etc).
+     * HVAC_TEMPERATURE_SET[AreaID] = xxx, etc).
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ_WRITE
@@ -877,13 +968,41 @@
         | VehicleArea:SEAT),
 
     /**
-     * Represents global power state for HVAC.  Setting this property to false
+     * Represents global power state for HVAC. Setting this property to false
      * MAY mark some properties that control individual HVAC features/subsystems
      * to UNAVAILABLE state. Setting this property to true MAY mark some
      * properties that control individual HVAC features/subsystems to AVAILABLE
      * state (unless any/all of them are UNAVAILABLE on their own individual
-     * merits).  The list of properties affected by HVAC_POWER_ON must be set
-     * in the VehiclePropConfig.configArray.
+     * merits).
+     *
+     * [Definition] HvacPower_DependentProperties: Properties that need HVAC to be
+     *   powered on in order to enable their functionality. For example, in some cars,
+     *   in order to turn on the AC, HVAC must be powered on first.
+     *
+     * HvacPower_DependentProperties list must be set in the
+     * VehiclePropConfig.configArray. HvacPower_DependentProperties must only contain
+     * properties that are associated with VehicleArea:SEAT. Properties that are not
+     * associated with VehicleArea:SEAT, for example, HVAC_DEFROSTER, must never
+     * depend on HVAC_POWER_ON property and must never be part of
+     * HvacPower_DependentProperties list.
+     *
+     * AreaID mapping for HVAC_POWER_ON property must contain all AreaIDs that
+     * HvacPower_DependentProperties are mapped to.
+     *
+     * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three back
+     *  seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). If the HVAC features (AC,
+     *  Temperature etc.) throughout the car are dependent on a single HVAC power
+     *  controller then HVAC_POWER_ON must be mapped to
+     *  [ROW_1_LEFT | ROW_1_RIGHT | ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT].
+     *
+     * Example 2: A car has two seats in the front row (ROW_1_LEFT, ROW_1_RIGHT) and
+     *   three seats in the second (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT) and third
+     *   rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). If the car has temperature
+     *   controllers in the front row which can operate entirely independently of
+     *   temperature controllers in the back of the vehicle, then HVAC_POWER_ON
+     *   must be mapped to a two element array:
+     *   - ROW_1_LEFT | ROW_1_RIGHT
+     *   - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ_WRITE
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index baffc78..ff7c0ee 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -1013,6 +1013,10 @@
 
         isPartialResult =
             (results.partialResult < request->numPartialResults);
+    } else if (resultSize > 0) {
+        request->collectedResult.append(reinterpret_cast<const camera_metadata_t*>(
+                    resultMetadata.data()));
+        isPartialResult = false;
     }
 
     hasInputBufferInRequest = request->hasInputBuffer;
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index 8904c68..86fe00d 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -64,9 +64,9 @@
 LOCAL_MODULE_STEM := compatibility_matrix.3.xml
 LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
 LOCAL_KERNEL_CONFIG_DATA_PATHS := \
-    4.4.0:$(my_kernel_config_data)/p/android-4.4 \
-    4.9.0:$(my_kernel_config_data)/p/android-4.9 \
-    4.14.0:$(my_kernel_config_data)/p/android-4.14 \
+    4.4.107:$(my_kernel_config_data)/p/android-4.4 \
+    4.9.84:$(my_kernel_config_data)/p/android-4.9 \
+    4.14.40:$(my_kernel_config_data)/p/android-4.14 \
 
 include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
 
diff --git a/compatibility_matrices/compatibility_matrix.3.xml b/compatibility_matrices/compatibility_matrix.3.xml
index 9bc76ea..2c5d431 100644
--- a/compatibility_matrices/compatibility_matrix.3.xml
+++ b/compatibility_matrices/compatibility_matrix.3.xml
@@ -88,6 +88,14 @@
         </interface>
     </hal>
     <hal format="hidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <version>2.0</version>
+        <interface>
+            <name>IBroadcastRadio</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
         <name>android.hardware.camera.provider</name>
         <version>2.4</version>
         <interface>
@@ -185,7 +193,7 @@
     </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.graphics.composer</name>
-        <version>2.1</version>
+        <version>2.1-2</version>
         <interface>
             <name>IComposer</name>
             <instance>default</instance>
@@ -193,7 +201,7 @@
     </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.graphics.mapper</name>
-        <version>2.0</version>
+        <version>2.0-1</version>
         <interface>
             <name>IMapper</name>
             <instance>default</instance>
@@ -258,7 +266,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.neuralnetworks</name>
-        <version>1.0</version>
+        <version>1.0-1</version>
         <interface>
             <name>IDevice</name>
             <regex-instance>.*</regex-instance>
diff --git a/current.txt b/current.txt
index 5ccd6ab..7d630d2 100644
--- a/current.txt
+++ b/current.txt
@@ -299,7 +299,7 @@
 3b17c1fdfc389e0abe626c37054954b07201127d890c2bc05d47613ec1f4de4f android.hardware.automotive.evs@1.0::types
 b3caf524c46a47d67e6453a34419e1881942d059e146cda740502670e9a752c3 android.hardware.automotive.vehicle@2.0::IVehicle
 7ce8728b27600e840cacf0a832f6942819fe535f9d3797ae052d5eef5065921c android.hardware.automotive.vehicle@2.0::IVehicleCallback
-9cf9690f559f8425fa86e409137a42435ca225505152f03736ac8f3773ef4f89 android.hardware.automotive.vehicle@2.0::types
+44c8b452186b65f5140a224721f238b76ed3adc42460f26b801b561593744c7e android.hardware.automotive.vehicle@2.0::types
 32cc50cc2a7658ec613c0c2dd2accbf6a05113b749852879e818b8b7b438db19 android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioHost
 ff4be64d7992f8bec97dff37f35450e79b3430c61f85f54322ce45bef229dc3b android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioOffload
 27f22d2e873e6201f9620cf4d8e2facb25bd0dd30a2b911e441b4600d560fa62 android.hardware.bluetooth.a2dp@1.0::types
@@ -327,7 +327,7 @@
 83e7a10ff3702147bd7ffa04567b20d407a3b16bbb7705644af44d919afe9103 android.hardware.gnss@1.1::IGnssMeasurementCallback
 0b96e0254e2168cfecb30c1ed5fb42681652cc00faa68c6e07568fafe64d1d50 android.hardware.graphics.common@1.1::types
 d9b40a5b09962a5a0780b10fe33a4e607e69e2e088fc83de88a584115b7cb1c0 android.hardware.graphics.composer@2.2::IComposer
-18eff12102db47b03a5fa906f8d4fd9018f0fb9236c663d457b8eac8d57c2937 android.hardware.graphics.composer@2.2::IComposerClient
+e7717f2ff2f6db43b24370ff08e14cd353da3004b32b17740e4a7ed4894b7e45 android.hardware.graphics.composer@2.2::IComposerClient
 dd83be076b6b3f10ed62ab34d8c8b95f2415961fb785200eb842e7bfb2b0ee92 android.hardware.graphics.mapper@2.1::IMapper
 675682dd3007805c985eaaec91612abc88f4c25b3431fb84070b7584a1a741fb android.hardware.health@2.0::IHealth
 434c4c32c00b0e54bb05e40c79503208b40f786a318029a2a4f66e34f10f2a76 android.hardware.health@2.0::IHealthInfoCallback
diff --git a/graphics/composer/2.2/IComposerClient.hal b/graphics/composer/2.2/IComposerClient.hal
index a6665a1..2f0a3cc 100644
--- a/graphics/composer/2.2/IComposerClient.hal
+++ b/graphics/composer/2.2/IComposerClient.hal
@@ -152,6 +152,11 @@
      * output of the display remains the same (subject to the note about protected
      * content in the description of setReadbackBuffer).
      *
+     * If the active configuration or color mode of this display has changed
+     * since a previous call to this function, it must be called again prior to
+     * setting a readback buffer such that the returned format and dataspace can
+     * be updated accordingly.
+     *
      * Parameters:
      * @param display - the display on which to create the layer.
      *
@@ -203,7 +208,13 @@
      *       must be non-NULL
      * @return error - is HWC2_ERROR_NONE or one of the following errors:
      *         BAD_DISPLAY - an invalid display handle was passed in
-     *         UNSUPPORTED if not supported on underlying HAL
+     *         NO_RESOURCES - the readback operation was successful, but
+     *                        resulted in a different validate result than would
+     *                        have occurred without readback
+     *         UNSUPPORTED - the readback operation was unsuccessful because of
+     *                       resource constraints, the presence of protected
+     *                       content, or other reasons; -1 must be returned for
+     *                       acquireFence
      *
      * See also:
      *   getReadbackBufferAttributes
diff --git a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
index 4eef4ec..03b6406 100644
--- a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
+++ b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
@@ -26,7 +26,6 @@
 #include <android/hardware/tetheroffload/control/1.0/types.h>
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netlink.h>
-#include <log/log.h>
 #include <net/if.h>
 #include <sys/socket.h>
 #include <unistd.h>
@@ -57,20 +56,16 @@
 constexpr const char* TEST_IFACE = "rmnet_data0";
 
 // We use #defines here so as to get local lamba captures and error message line numbers
-#define ASSERT_TRUE_CALLBACK                            \
-    [&](bool success, std::string errMsg) {             \
-        if (!success) {                                 \
-            ALOGI("Error message: %s", errMsg.c_str()); \
-        }                                               \
-        ASSERT_TRUE(success);                           \
+#define ASSERT_TRUE_CALLBACK                                                    \
+    [&](bool success, std::string errMsg) {                                     \
+        std::string msg = StringPrintf("unexpected error: %s", errMsg.c_str()); \
+        ASSERT_TRUE(success) << msg;                                            \
     }
 
-#define ASSERT_FALSE_CALLBACK                           \
-    [&](bool success, std::string errMsg) {             \
-        if (!success) {                                 \
-            ALOGI("Error message: %s", errMsg.c_str()); \
-        }                                               \
-        ASSERT_FALSE(success);                          \
+#define ASSERT_FALSE_CALLBACK                                                 \
+    [&](bool success, std::string errMsg) {                                   \
+        std::string msg = StringPrintf("expected error: %s", errMsg.c_str()); \
+        ASSERT_FALSE(success) << msg;                                         \
     }
 
 #define ASSERT_ZERO_BYTES_CALLBACK            \
@@ -188,10 +183,9 @@
 
     void initOffload(const bool expected_result) {
         auto init_cb = [&](bool success, std::string errMsg) {
-            if (!success) {
-                ALOGI("Error message: %s", errMsg.c_str());
-            }
-            ASSERT_EQ(expected_result, success);
+            std::string msg = StringPrintf("Unexpectedly %s to init offload: %s",
+                                           success ? "succeeded" : "failed", errMsg.c_str());
+            ASSERT_EQ(expected_result, success) << msg;
         };
         const Return<void> ret = control->initOffload(control_cb, init_cb);
         ASSERT_TRUE(ret.isOk());
@@ -204,15 +198,12 @@
 
     void stopOffload(const ExpectBoolean value) {
         auto cb = [&](bool success, const hidl_string& errMsg) {
-            if (!success) {
-                ALOGI("Error message: %s", errMsg.c_str());
-            }
             switch (value) {
                 case ExpectBoolean::False:
-                    ASSERT_EQ(false, success);
+                    ASSERT_EQ(false, success) << "Unexpectedly able to stop offload: " << errMsg;
                     break;
                 case ExpectBoolean::True:
-                    ASSERT_EQ(true, success);
+                    ASSERT_EQ(true, success) << "Unexpectedly failed to stop offload: " << errMsg;
                     break;
                 case ExpectBoolean::Ignored:
                     break;
@@ -289,8 +280,11 @@
     if (!interfaceIsUp(TEST_IFACE)) {
         return;
     }
-    stopOffload(ExpectBoolean::True);  // balance out initOffload(true)
+    SCOPED_TRACE("Expecting stopOffload to succeed");
+    stopOffload(ExpectBoolean::Ignored);  // balance out initOffload(true)
+    SCOPED_TRACE("Expecting stopOffload to fail the first time");
     stopOffload(ExpectBoolean::False);
+    SCOPED_TRACE("Expecting stopOffload to fail the second time");
     stopOffload(ExpectBoolean::False);
 }
 
diff --git a/wifi/1.2/default/Android.mk b/wifi/1.2/default/Android.mk
index 978cf63..3919690 100644
--- a/wifi/1.2/default/Android.mk
+++ b/wifi/1.2/default/Android.mk
@@ -27,6 +27,9 @@
 ifdef WIFI_HIDL_FEATURE_DUAL_INTERFACE
 LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DUAL_INTERFACE
 endif
+ifdef WIFI_HIDL_FEATURE_DISABLE_AP
+LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP
+endif
 LOCAL_SRC_FILES := \
     hidl_struct_util.cpp \
     hidl_sync_util.cpp \
diff --git a/wifi/1.2/default/tests/mock_wifi_feature_flags.h b/wifi/1.2/default/tests/mock_wifi_feature_flags.h
index 8cf1d4b..2a36dd5 100644
--- a/wifi/1.2/default/tests/mock_wifi_feature_flags.h
+++ b/wifi/1.2/default/tests/mock_wifi_feature_flags.h
@@ -34,6 +34,7 @@
 
     MOCK_METHOD0(isAwareSupported, bool());
     MOCK_METHOD0(isDualInterfaceSupported, bool());
+    MOCK_METHOD0(isApDisabled, bool());
 };
 
 }  // namespace feature_flags
diff --git a/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
index 3928c9a..8722d0a 100644
--- a/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
@@ -48,6 +48,8 @@
             .WillRepeatedly(testing::Return(false));
         EXPECT_CALL(*feature_flags_, isDualInterfaceSupported())
             .WillRepeatedly(testing::Return(false));
+        EXPECT_CALL(*feature_flags_, isApDisabled())
+            .WillRepeatedly(testing::Return(false));
     }
 
     void setupV1_AwareIfaceCombination() {
@@ -55,6 +57,17 @@
             .WillRepeatedly(testing::Return(true));
         EXPECT_CALL(*feature_flags_, isDualInterfaceSupported())
             .WillRepeatedly(testing::Return(false));
+        EXPECT_CALL(*feature_flags_, isApDisabled())
+            .WillRepeatedly(testing::Return(false));
+    }
+
+    void setupV1_AwareDisabledApIfaceCombination() {
+        EXPECT_CALL(*feature_flags_, isAwareSupported())
+            .WillRepeatedly(testing::Return(true));
+        EXPECT_CALL(*feature_flags_, isDualInterfaceSupported())
+            .WillRepeatedly(testing::Return(false));
+        EXPECT_CALL(*feature_flags_, isApDisabled())
+            .WillRepeatedly(testing::Return(true));
     }
 
     void setupV2_AwareIfaceCombination() {
@@ -62,6 +75,17 @@
             .WillRepeatedly(testing::Return(true));
         EXPECT_CALL(*feature_flags_, isDualInterfaceSupported())
             .WillRepeatedly(testing::Return(true));
+        EXPECT_CALL(*feature_flags_, isApDisabled())
+            .WillRepeatedly(testing::Return(false));
+    }
+
+    void setupV2_AwareDisabledApIfaceCombination() {
+        EXPECT_CALL(*feature_flags_, isAwareSupported())
+            .WillRepeatedly(testing::Return(true));
+        EXPECT_CALL(*feature_flags_, isDualInterfaceSupported())
+            .WillRepeatedly(testing::Return(true));
+        EXPECT_CALL(*feature_flags_, isApDisabled())
+            .WillRepeatedly(testing::Return(true));
     }
 
     void assertNumberOfModes(uint32_t num_modes) {
@@ -515,6 +539,39 @@
     ASSERT_FALSE(ap_iface_name.empty());
     ASSERT_NE(sta_iface_name, ap_iface_name);
 }
+
+////////// V1 Iface Combinations when AP creation is disabled //////////
+class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
+ public:
+  void SetUp() override {
+    setupV1_AwareDisabledApIfaceCombination();
+    WifiChipTest::SetUp();
+  }
+};
+
+TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest,
+       StaMode_CreateSta_ShouldSucceed) {
+  findModeAndConfigureForIfaceType(IfaceType::STA);
+  ASSERT_FALSE(createIface(IfaceType::STA).empty());
+  ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
+////////// V2 Iface Combinations when AP creation is disabled //////////
+class WifiChipV2_AwareDisabledApIfaceCombinationTest: public WifiChipTest {
+ public:
+  void SetUp() override {
+    setupV2_AwareDisabledApIfaceCombination();
+    WifiChipTest::SetUp();
+  }
+};
+
+TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest,
+       CreateSta_ShouldSucceed) {
+  findModeAndConfigureForIfaceType(IfaceType::STA);
+  ASSERT_FALSE(createIface(IfaceType::STA).empty());
+  ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
 }  // namespace implementation
 }  // namespace V1_2
 }  // namespace wifi
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index ab96ef1..3bd0557 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -1211,10 +1211,17 @@
             {chip_iface_combination_limit_1, chip_iface_combination_limit_2}};
         const IWifiChip::ChipIfaceCombination chip_iface_combination_2 = {
             {chip_iface_combination_limit_1, chip_iface_combination_limit_3}};
-        const IWifiChip::ChipMode chip_mode = {
+        if (feature_flags_.lock()->isApDisabled()) {
+          const IWifiChip::ChipMode chip_mode = {
+              kV2ChipModeId,
+              {chip_iface_combination_2}};
+          modes_ = {chip_mode};
+        } else {
+          const IWifiChip::ChipMode chip_mode = {
             kV2ChipModeId,
             {chip_iface_combination_1, chip_iface_combination_2}};
-        modes_ = {chip_mode};
+          modes_ = {chip_mode};
+        }
     } else {
         // V1 Iface combinations for Mode Id = 0. (STA Mode)
         const IWifiChip::ChipIfaceCombinationLimit
@@ -1238,7 +1245,11 @@
             {ap_chip_iface_combination_limit}};
         const IWifiChip::ChipMode ap_chip_mode = {kV1ApChipModeId,
                                                   {ap_chip_iface_combination}};
-        modes_ = {sta_chip_mode, ap_chip_mode};
+        if (feature_flags_.lock()->isApDisabled()) {
+          modes_ = {sta_chip_mode};
+        } else {
+          modes_ = {sta_chip_mode, ap_chip_mode};
+        }
     }
 }
 
diff --git a/wifi/1.2/default/wifi_feature_flags.cpp b/wifi/1.2/default/wifi_feature_flags.cpp
index 554d4d5..778944d 100644
--- a/wifi/1.2/default/wifi_feature_flags.cpp
+++ b/wifi/1.2/default/wifi_feature_flags.cpp
@@ -27,6 +27,12 @@
 #else
 static const bool wifiHidlFeatureDualInterface = false;
 #endif  // WIFI_HIDL_FEATURE_DUAL_INTERFACE
+#ifdef WIFI_HIDL_FEATURE_DISABLE_AP
+static const bool wifiHidlFeatureDisableAp = true;
+#else
+static const bool wifiHidlFeatureDisableAp = false;
+#endif  // WIFI_HIDL_FEATURE_DISABLE_AP
+
 }  // namespace
 
 namespace android {
@@ -41,6 +47,9 @@
 bool WifiFeatureFlags::isDualInterfaceSupported() {
     return wifiHidlFeatureDualInterface;
 }
+bool WifiFeatureFlags::isApDisabled() {
+  return wifiHidlFeatureDisableAp;
+}
 
 }  // namespace feature_flags
 }  // namespace implementation
diff --git a/wifi/1.2/default/wifi_feature_flags.h b/wifi/1.2/default/wifi_feature_flags.h
index dc0c1ff..4a7b2d2 100644
--- a/wifi/1.2/default/wifi_feature_flags.h
+++ b/wifi/1.2/default/wifi_feature_flags.h
@@ -31,6 +31,7 @@
 
     virtual bool isAwareSupported();
     virtual bool isDualInterfaceSupported();
+    virtual bool isApDisabled();
 };
 
 }  // namespace feature_flags