Merge "Fix errorprone warnings that should be errors"
diff --git a/Android.bp b/Android.bp
index 619a390..00294cb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -74,6 +74,7 @@
         "zxing-core-1.7",
         "android.hardware.dumpstate-V1.0-java",
         "android.hardware.dumpstate-V1.1-java",
+        "android.hardware.dumpstate-V1-java",
         "lottie",
         "WifiTrackerLib",
         "SettingsLibActivityEmbedding",
diff --git a/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceController.java b/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceController.java
index e1db74d..051cede 100644
--- a/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceController.java
+++ b/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceController.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.hardware.dumpstate.V1_0.IDumpstateDevice;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -40,8 +41,12 @@
 
     private static final String ENABLE_VERBOSE_VENDOR_LOGGING_KEY = "enable_verbose_vendor_logging";
     private static final int DUMPSTATE_HAL_VERSION_UNKNOWN = -1;
-    private static final int DUMPSTATE_HAL_VERSION_1_0 = 0;
-    private static final int DUMPSTATE_HAL_VERSION_1_1 = 1;
+    private static final int DUMPSTATE_HAL_VERSION_1_0 = 0; // HIDL v1.0
+    private static final int DUMPSTATE_HAL_VERSION_1_1 = 1; // HIDL v1.1
+    private static final int DUMPSTATE_HAL_VERSION_2_0 = 2; // AIDL v1
+
+    private static final String DUMP_STATE_AIDL_SERVICE_NAME =
+            android.hardware.dumpstate.IDumpstateDevice.DESCRIPTOR + "/default";
 
     private int mDumpstateHalVersion;
 
@@ -57,9 +62,8 @@
 
     @Override
     public boolean isAvailable() {
-        // Only show preference when IDumpstateDevice v1.1 is avalaible
-        // This is temperary strategy that may change later.
-        return isIDumpstateDeviceV1_1ServiceAvailable();
+        // Only show preference when IDumpstateDevice AIDL or HIDL v1.1 service is available
+        return isIDumpstateDeviceAidlServiceAvailable() || isIDumpstateDeviceV1_1ServiceAvailable();
     }
 
     @Override
@@ -86,15 +90,31 @@
     boolean isIDumpstateDeviceV1_1ServiceAvailable() {
         IDumpstateDevice service = getDumpstateDeviceService();
         if (service == null) {
-            if (DBG) Log.d(TAG, "IDumpstateDevice service is not available.");
+            if (DBG) Log.d(TAG, "IDumpstateDevice v1.1 service is not available.");
         }
-        return service != null && mDumpstateHalVersion >= DUMPSTATE_HAL_VERSION_1_1;
+        return service != null && mDumpstateHalVersion == DUMPSTATE_HAL_VERSION_1_1;
+    }
+
+    @VisibleForTesting
+    boolean isIDumpstateDeviceAidlServiceAvailable() {
+        android.hardware.dumpstate.IDumpstateDevice aidlService = getDumpstateDeviceAidlService();
+        return aidlService != null;
     }
 
     @VisibleForTesting
     void setVerboseLoggingEnabled(boolean enable) {
-        IDumpstateDevice service = getDumpstateDeviceService();
+        // First check if AIDL service is available
+        android.hardware.dumpstate.IDumpstateDevice aidlService = getDumpstateDeviceAidlService();
+        if (aidlService != null) {
+            try {
+                aidlService.setVerboseLoggingEnabled(enable);
+            } catch (RemoteException re) {
+                if (DBG) Log.e(TAG, "aidlService.setVerboseLoggingEnabled fail: " + re);
+            }
+        }
 
+        // Then check HIDL v1.1 service
+        IDumpstateDevice service = getDumpstateDeviceService();
         if (service == null || mDumpstateHalVersion < DUMPSTATE_HAL_VERSION_1_1) {
             if (DBG) Log.d(TAG, "setVerboseLoggingEnabled not supported.");
             return;
@@ -107,14 +127,24 @@
                 service11.setVerboseLoggingEnabled(enable);
             }
         } catch (RemoteException | RuntimeException e) {
-            if (DBG) Log.e(TAG, "setVerboseLoggingEnabled fail: " + e);
+            if (DBG) Log.e(TAG, "HIDL v1.1 setVerboseLoggingEnabled fail: " + e);
         }
     }
 
     @VisibleForTesting
     boolean getVerboseLoggingEnabled() {
-        IDumpstateDevice service = getDumpstateDeviceService();
+        // First check if AIDL service is available
+        android.hardware.dumpstate.IDumpstateDevice aidlService = getDumpstateDeviceAidlService();
+        if (aidlService != null) {
+            try {
+                return aidlService.getVerboseLoggingEnabled();
+            } catch (RemoteException re) {
+                if (DBG) Log.e(TAG, "aidlService.getVerboseLoggingEnabled fail: " + re);
+            }
+        }
 
+        // Then check HIDL v1.1 service
+        IDumpstateDevice service = getDumpstateDeviceService();
         if (service == null || mDumpstateHalVersion < DUMPSTATE_HAL_VERSION_1_1) {
             if (DBG) Log.d(TAG, "getVerboseLoggingEnabled not supported.");
             return false;
@@ -127,7 +157,7 @@
                 return service11.getVerboseLoggingEnabled();
             }
         } catch (RemoteException | RuntimeException e) {
-            if (DBG) Log.e(TAG, "getVerboseLoggingEnabled fail: " + e);
+            if (DBG) Log.e(TAG, "HIDL v1.1 getVerboseLoggingEnabled fail: " + e);
         }
         return false;
     }
@@ -141,6 +171,7 @@
                     .getService(true /* retry */);
             mDumpstateHalVersion = DUMPSTATE_HAL_VERSION_1_1;
         } catch (NoSuchElementException | RemoteException e) {
+            if (DBG) Log.e(TAG, "Get HIDL v1.1 service fail: " + e);
         }
 
         if (service == null) {
@@ -149,6 +180,7 @@
                         .getService(true /* retry */);
                 mDumpstateHalVersion = DUMPSTATE_HAL_VERSION_1_0;
             } catch (NoSuchElementException | RemoteException e) {
+                if (DBG) Log.e(TAG, "Get HIDL v1.0 service fail: " + e);
             }
         }
 
@@ -157,4 +189,24 @@
         }
         return service;
     }
+
+    /**
+     * Return a {@link android.hardware.dumpstate.IDumpstateDevice} instance or null if service is
+     * not available.
+     */
+    @VisibleForTesting
+    @Nullable android.hardware.dumpstate.IDumpstateDevice getDumpstateDeviceAidlService() {
+        android.hardware.dumpstate.IDumpstateDevice service = null;
+        try {
+            service = android.hardware.dumpstate.IDumpstateDevice.Stub.asInterface(
+                    ServiceManager.waitForDeclaredService(DUMP_STATE_AIDL_SERVICE_NAME));
+        } catch (NoSuchElementException e) {
+            if (DBG) Log.e(TAG, "Get AIDL service fail: " + e);
+        }
+
+        if (service != null) {
+            mDumpstateHalVersion = DUMPSTATE_HAL_VERSION_2_0;
+        }
+        return service;
+    }
 }
diff --git a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
index 9992ae7..a64ec89 100644
--- a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
+++ b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
@@ -141,6 +141,8 @@
             return;
         }
 
+        // Highlight request accepted
+        mHighlightRequested = true;
         // Collapse app bar after 300 milliseconds.
         if (appBarLayout != null) {
             root.postDelayed(() -> {
@@ -152,17 +154,37 @@
         recyclerView.setItemAnimator(null);
         // Scroll to correct position after 600 milliseconds.
         root.postDelayed(() -> {
-            mHighlightRequested = true;
-            recyclerView.smoothScrollToPosition(position);
-            mHighlightPosition = position;
+            if (ensureHighlightPosition()) {
+                recyclerView.smoothScrollToPosition(mHighlightPosition);
+            }
         }, DELAY_HIGHLIGHT_DURATION_MILLIS);
 
         // Highlight preference after 900 milliseconds.
         root.postDelayed(() -> {
-            notifyItemChanged(position);
+            if (ensureHighlightPosition()) {
+                notifyItemChanged(mHighlightPosition);
+            }
         }, DELAY_COLLAPSE_DURATION_MILLIS + DELAY_HIGHLIGHT_DURATION_MILLIS);
     }
 
+    /**
+     * Make sure we highlight the real-wanted position in case of preference position already
+     * changed when the delay time comes.
+     */
+    private boolean ensureHighlightPosition() {
+        if (TextUtils.isEmpty(mHighlightKey)) {
+            return false;
+        }
+        final int position = getPreferenceAdapterPosition(mHighlightKey);
+        final boolean allowHighlight = position >= 0;
+        if (allowHighlight && mHighlightPosition != position) {
+            Log.w(TAG, "EnsureHighlight: position has changed since last highlight request");
+            // Make sure RecyclerView always uses latest correct position to avoid exceptions.
+            mHighlightPosition = position;
+        }
+        return allowHighlight;
+    }
+
     public boolean isHighlightRequested() {
         return mHighlightRequested;
     }
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
index 492a228..0c3d769 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
@@ -85,8 +85,8 @@
 
     protected static final String FRAGMENT_BUNDLE_SUBID = "subId";
 
-    public static final int LAUCH_APP_ACTIVATE = 0;
-    public static final int LAUCH_APP_UPDATE = 1;
+    public static final int LAUNCH_APP_ACTIVATE = 0;
+    public static final int LAUNCH_APP_UPDATE = 1;
 
     //UI objects
     private SettingsMainSwitchPreference mSwitchBar;
@@ -179,7 +179,7 @@
             preference -> {
                 final Intent carrierAppIntent = getCarrierActivityIntent();
                 if (carrierAppIntent != null) {
-                    carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_UPDATE);
+                    carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUNCH_APP_UPDATE);
                     startActivity(carrierAppIntent);
                 }
                 return true;
@@ -493,7 +493,7 @@
      * Return null when no activity found.
      */
     private Intent getCarrierActivityIntent() {
-        // Retrive component name from carrier config
+        // Retrieve component name from carrier config
         final CarrierConfigManager configManager =
                 getActivity().getSystemService(CarrierConfigManager.class);
         if (configManager == null) return null;
@@ -549,7 +549,7 @@
                     // Call address management activity before turning on WFC
                     final Intent carrierAppIntent = getCarrierActivityIntent();
                     if (carrierAppIntent != null) {
-                        carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_ACTIVATE);
+                        carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUNCH_APP_ACTIVATE);
                         startActivityForResult(carrierAppIntent,
                                 REQUEST_CHECK_WFC_EMERGENCY_ADDRESS);
                     } else {
diff --git a/tests/robotests/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceControllerTest.java
index 6145939..8e62521 100644
--- a/tests/robotests/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceControllerTest.java
@@ -47,6 +47,8 @@
     private PreferenceScreen mPreferenceScreen;
     @Mock
     IDumpstateDevice mIDumpstateDevice;
+    @Mock
+    android.hardware.dumpstate.IDumpstateDevice mIDumpstateDeviceAidl;
 
     private Context mContext;
     private EnableVerboseVendorLoggingPreferenceController mController;
@@ -57,6 +59,7 @@
         mContext = RuntimeEnvironment.application;
         mController = spy(new EnableVerboseVendorLoggingPreferenceController(mContext));
         doReturn(mIDumpstateDevice).when(mController).getDumpstateDeviceService();
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
 
         // mock with Dumpstate HAL v1.1
         Field f = EnableVerboseVendorLoggingPreferenceController.class
@@ -70,7 +73,9 @@
     }
 
     @Test
-    public void onPreferenceChange_settingEnable_enableVendorLoggingShouldBeOn() throws Exception {
+    public void onPreferenceChange_settingEnableByHidl_enableVendorLoggingShouldBeOn()
+            throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(true).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.onPreferenceChange(mPreference, true /* new value */);
@@ -80,8 +85,21 @@
     }
 
     @Test
-    public void onPreferenceChange_settingDisable_enableVendorLoggingShouldBeOff()
+    public void onPreferenceChange_settingEnableByAidl_enableVendorLoggingShouldBeOn()
             throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(true).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.onPreferenceChange(mPreference, true /* new value */);
+
+        final boolean enabled = mController.getVerboseLoggingEnabled();
+        assertTrue(enabled);
+    }
+
+    @Test
+    public void onPreferenceChange_settingDisableByHidl_enableVendorLoggingShouldBeOff()
+            throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(false).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.onPreferenceChange(mPreference,  false /* new value */);
@@ -91,7 +109,20 @@
     }
 
     @Test
-    public void updateState_settingDisabled_preferenceShouldNotBeChecked() throws Exception {
+    public void onPreferenceChange_settingDisableByAidl_enableVendorLoggingShouldBeOff()
+            throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(false).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.onPreferenceChange(mPreference,  false /* new value */);
+
+        final boolean enabled = mController.getVerboseLoggingEnabled();
+        assertFalse(enabled);
+    }
+
+    @Test
+    public void updateState_settingDisabledByHidl_preferenceShouldNotBeChecked() throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(false).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.setVerboseLoggingEnabled(false);
@@ -101,7 +132,19 @@
     }
 
     @Test
-    public void updateState_settingEnabled_preferenceShouldBeChecked() throws Exception {
+    public void updateState_settingDisabledByAidl_preferenceShouldNotBeChecked() throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(false).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.setVerboseLoggingEnabled(false);
+        mController.updateState(mPreference);
+
+        verify(mPreference).setChecked(false);
+    }
+
+    @Test
+    public void updateState_settingEnabledByHidl_preferenceShouldBeChecked() throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(true).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.setVerboseLoggingEnabled(true);
@@ -111,7 +154,19 @@
     }
 
     @Test
-    public void onDeveloperOptionDisabled_shouldDisablePreference() throws Exception {
+    public void updateState_settingEnabledByAidl_preferenceShouldBeChecked() throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(true).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.setVerboseLoggingEnabled(true);
+        mController.updateState(mPreference);
+
+        verify(mPreference).setChecked(true);
+    }
+
+    @Test
+    public void onDeveloperOptionDisabled_byHidl_shouldDisablePreference() throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(false).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.onDeveloperOptionsSwitchDisabled();
@@ -121,4 +176,17 @@
         verify(mPreference).setChecked(false);
         verify(mPreference).setEnabled(false);
     }
+
+    @Test
+    public void onDeveloperOptionDisabled_byAidl_shouldDisablePreference() throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(false).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.onDeveloperOptionsSwitchDisabled();
+
+        final boolean enabled = mController.getVerboseLoggingEnabled();
+        assertFalse(enabled);
+        verify(mPreference).setChecked(false);
+        verify(mPreference).setEnabled(false);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
index e297b78..2453a30 100644
--- a/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
@@ -129,7 +129,7 @@
     }
 
     @Test
-    public void adjustInitialExpandedChildCount_hasHightlightKey_shouldExpandAllChildren() {
+    public void adjustInitialExpandedChildCount_hasHighlightKey_shouldExpandAllChildren() {
         final Bundle args = new Bundle();
         when(mFragment.getArguments()).thenReturn(args);
         args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, "testkey");
@@ -208,7 +208,7 @@
     }
 
     @Test
-    public void updateBackground_reuseHightlightedRowForNormalRow_shouldResetBackgroundAndTag() {
+    public void updateBackground_reuseHighlightedRowForNormalRow_shouldResetBackgroundAndTag() {
         ReflectionHelpers.setField(mAdapter, "mHighlightPosition", 10);
         mViewHolder.itemView.setTag(R.id.preference_highlighted, true);