Merge "[LeAudio] New QR code scanner UIs and modify local API"
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 27f3fc5..8081c15 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -146,11 +146,17 @@
     ],
 }
 
-filegroup {
-    name: "framework-services-net-module-wifi-shared-srcs",
-    srcs: [
-        "android/util/LocalLog.java",
+java_library {
+    name: "modules-utils-locallog",
+    srcs: ["android/util/LocalLog.java"],
+    libs: ["unsupportedappusage"],
+    sdk_version: "module_current",
+    min_sdk_version: "30",
+    apex_available: [
+        "//apex_available:anyapex",
+        "//apex_available:platform",
     ],
+    visibility: ["//visibility:public"],
 }
 
 // keep these files in sync with the package/Tethering/jarjar-rules.txt and
@@ -375,15 +381,6 @@
     ],
 }
 
-// Avoid including Parcelable classes as we don't want to have two copies of
-// Parcelable cross the process.
-filegroup {
-    name: "framework-cellbroadcast-shared-srcs",
-    srcs: [
-        "android/util/LocalLog.java",
-    ],
-}
-
 java_library {
     name: "modules-utils-statemachine",
     srcs: [
diff --git a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
index 5c9989e..76ee097 100644
--- a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
+++ b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
@@ -52,6 +52,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.net.ProtocolException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
@@ -161,9 +162,12 @@
     @NonNull
     private static ArrayList<File> getPlatformFileListForPrefix(@NonNull @Prefix String prefix) {
         final ArrayList<File> list = new ArrayList<>();
-        final File platformFiles = new File(getPlatformBaseDir(), "netstats");
+        final File platformFiles = getPlatformBaseDir();
         if (platformFiles.exists()) {
-            for (String name : platformFiles.list()) {
+            final String[] files = platformFiles.list();
+            if (files == null) return list;
+            Arrays.sort(files);
+            for (String name : files) {
                 // Skip when prefix doesn't match.
                 if (!name.startsWith(prefix + ".")) continue;
 
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 4b3af15..5bc48c5 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.util;
 
+import android.annotation.NonNull;
 import android.os.FileUtils;
 import android.util.Log;
 
@@ -282,6 +283,20 @@
     }
 
     /**
+     * Process a single file atomically, with the given start and end timestamps.
+     * If a file with these exact start and end timestamps does not exist, a new
+     * empty file will be written.
+     */
+    public void rewriteSingle(@NonNull Rewriter rewriter, long startTimeMillis, long endTimeMillis)
+            throws IOException {
+        final FileInfo info = new FileInfo(mPrefix);
+
+        info.startMillis = startTimeMillis;
+        info.endMillis = endTimeMillis;
+        rewriteSingle(rewriter, info.build());
+    }
+
+    /**
      * Read any rotated data that overlap the requested time range.
      */
     public void readMatching(Reader reader, long matchStartMillis, long matchEndMillis)
diff --git a/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java b/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java
index de45ea5..d3fe4a7 100644
--- a/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java
+++ b/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java
@@ -47,7 +47,7 @@
  * Annotation processor for {@link SearchIndexable} that generates {@link SearchIndexableResources}
  * subclasses.
  */
-@SupportedSourceVersion(SourceVersion.RELEASE_8)
+@SupportedSourceVersion(SourceVersion.RELEASE_9)
 @SupportedAnnotationTypes({"com.android.settingslib.search.SearchIndexable"})
 public class IndexableProcessor extends AbstractProcessor {
 
diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java
index 2845fbf..69f6d3a 100644
--- a/services/core/java/com/android/server/adb/AdbService.java
+++ b/services/core/java/com/android/server/adb/AdbService.java
@@ -56,6 +56,7 @@
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.testharness.TestHarnessModeService;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -163,18 +164,8 @@
         }
     }
 
-    private void initAdbState() {
+    private void registerContentObservers() {
         try {
-            /*
-             * Use the normal bootmode persistent prop to maintain state of adb across
-             * all boot modes.
-             */
-            mIsAdbUsbEnabled = containsFunction(
-                    SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""),
-                    UsbManager.USB_FUNCTION_ADB);
-            mIsAdbWifiEnabled = "1".equals(
-                    SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"));
-
             // register observer to listen for settings changes
             mObserver = new AdbSettingsObserver();
             mContentResolver.registerContentObserver(
@@ -184,7 +175,7 @@
                     Settings.Global.getUriFor(Settings.Global.ADB_WIFI_ENABLED),
                     false, mObserver);
         } catch (Exception e) {
-            Slog.e(TAG, "Error in initAdbState", e);
+            Slog.e(TAG, "Error in registerContentObservers", e);
         }
     }
 
@@ -248,7 +239,7 @@
         mContentResolver = context.getContentResolver();
         mDebuggingManager = new AdbDebuggingManager(context);
 
-        initAdbState();
+        registerContentObservers();
         LocalServices.addService(AdbManagerInternal.class, new AdbManagerInternalImpl());
     }
 
@@ -259,10 +250,23 @@
     public void systemReady() {
         if (DEBUG) Slog.d(TAG, "systemReady");
 
+        /*
+         * Use the normal bootmode persistent prop to maintain state of adb across
+         * all boot modes.
+         */
+        mIsAdbUsbEnabled = containsFunction(
+                SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""),
+                UsbManager.USB_FUNCTION_ADB);
+        boolean shouldEnableAdbUsb = mIsAdbUsbEnabled
+                || SystemProperties.getBoolean(
+                        TestHarnessModeService.TEST_HARNESS_MODE_PROPERTY, false);
+        mIsAdbWifiEnabled = "1".equals(
+                SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"));
+
         // make sure the ADB_ENABLED setting value matches the current state
         try {
             Settings.Global.putInt(mContentResolver,
-                    Settings.Global.ADB_ENABLED, mIsAdbUsbEnabled ? 1 : 0);
+                    Settings.Global.ADB_ENABLED, shouldEnableAdbUsb ? 1 : 0);
             Settings.Global.putInt(mContentResolver,
                     Settings.Global.ADB_WIFI_ENABLED, mIsAdbWifiEnabled ? 1 : 0);
         } catch (SecurityException e) {
@@ -272,7 +276,7 @@
     }
 
     /**
-     * Callend in response to {@code SystemService.PHASE_BOOT_COMPLETED} from {@code SystemServer}.
+     * Called in response to {@code SystemService.PHASE_BOOT_COMPLETED} from {@code SystemServer}.
      */
     public void bootCompleted() {
         if (DEBUG) Slog.d(TAG, "boot completed");
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index e78347b..511aef2 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -3152,13 +3152,8 @@
             cancelHandleNetworkLostTimeout();
 
             synchronized (Vpn.this) {
-                String category = "";
-                int errorClass = 0;
-                int errorCode = 0;
                 if (exception instanceof IkeProtocolException) {
                     final IkeProtocolException ikeException = (IkeProtocolException) exception;
-                    category = VpnManager.CATEGORY_EVENT_IKE_ERROR;
-                    errorCode = ikeException.getErrorType();
 
                     switch (ikeException.getErrorType()) {
                         case IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN: // Fallthrough
@@ -3168,51 +3163,103 @@
                         case IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED: // Fallthrough
                         case IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE:
                             // All the above failures are configuration errors, and are terminal
-                            errorClass = VpnManager.ERROR_CLASS_NOT_RECOVERABLE;
-                            break;
+                            // TODO(b/230548427): Remove SDK check once VPN related stuff are
+                            //  decoupled from ConnectivityServiceTest.
+                            if (SdkLevel.isAtLeastT()) {
+                                sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_IKE_ERROR,
+                                        VpnManager.ERROR_CLASS_NOT_RECOVERABLE,
+                                        ikeException.getErrorType(),
+                                        getPackage(), mSessionKey, makeVpnProfileStateLocked(),
+                                        mActiveNetwork,
+                                        getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
+                                                mUnderlyingNetworkCapabilities),
+                                        getRedactedLinkPropertiesOfUnderlyingNetwork(
+                                                mUnderlyingLinkProperties));
+                            }
+                            markFailedAndDisconnect(exception);
+                            return;
                         // All other cases possibly recoverable.
                         default:
                             // All the above failures are configuration errors, and are terminal
-                            errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
+                            // TODO(b/230548427): Remove SDK check once VPN related stuff are
+                            //  decoupled from ConnectivityServiceTest.
+                            if (SdkLevel.isAtLeastT()) {
+                                sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_IKE_ERROR,
+                                        VpnManager.ERROR_CLASS_RECOVERABLE,
+                                        ikeException.getErrorType(),
+                                        getPackage(), mSessionKey, makeVpnProfileStateLocked(),
+                                        mActiveNetwork,
+                                        getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
+                                                mUnderlyingNetworkCapabilities),
+                                        getRedactedLinkPropertiesOfUnderlyingNetwork(
+                                                mUnderlyingLinkProperties));
+                            }
                     }
                 } else if (exception instanceof IllegalArgumentException) {
                     // Failed to build IKE/ChildSessionParams; fatal profile configuration error
                     markFailedAndDisconnect(exception);
                     return;
                 } else if (exception instanceof IkeNetworkLostException) {
-                    category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
-                    errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
-                    errorCode = VpnManager.ERROR_CODE_NETWORK_LOST;
+                    // TODO(b/230548427): Remove SDK check once VPN related stuff are
+                    //  decoupled from ConnectivityServiceTest.
+                    if (SdkLevel.isAtLeastT()) {
+                        sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_NETWORK_ERROR,
+                                VpnManager.ERROR_CLASS_RECOVERABLE,
+                                VpnManager.ERROR_CODE_NETWORK_LOST,
+                                getPackage(), mSessionKey, makeVpnProfileStateLocked(),
+                                mActiveNetwork,
+                                getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
+                                        mUnderlyingNetworkCapabilities),
+                                getRedactedLinkPropertiesOfUnderlyingNetwork(
+                                        mUnderlyingLinkProperties));
+                    }
                 } else if (exception instanceof IkeNonProtocolException) {
-                    category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
-                    errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
                     if (exception.getCause() instanceof UnknownHostException) {
-                        errorCode = VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST;
+                        // TODO(b/230548427): Remove SDK check once VPN related stuff are
+                        //  decoupled from ConnectivityServiceTest.
+                        if (SdkLevel.isAtLeastT()) {
+                            sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_NETWORK_ERROR,
+                                    VpnManager.ERROR_CLASS_RECOVERABLE,
+                                    VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST,
+                                    getPackage(), mSessionKey, makeVpnProfileStateLocked(),
+                                    mActiveNetwork,
+                                    getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
+                                            mUnderlyingNetworkCapabilities),
+                                    getRedactedLinkPropertiesOfUnderlyingNetwork(
+                                            mUnderlyingLinkProperties));
+                        }
                     } else if (exception.getCause() instanceof IkeTimeoutException) {
-                        errorCode = VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT;
+                        // TODO(b/230548427): Remove SDK check once VPN related stuff are
+                        //  decoupled from ConnectivityServiceTest.
+                        if (SdkLevel.isAtLeastT()) {
+                            sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_NETWORK_ERROR,
+                                    VpnManager.ERROR_CLASS_RECOVERABLE,
+                                    VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT,
+                                    getPackage(), mSessionKey, makeVpnProfileStateLocked(),
+                                    mActiveNetwork,
+                                    getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
+                                            mUnderlyingNetworkCapabilities),
+                                    getRedactedLinkPropertiesOfUnderlyingNetwork(
+                                            mUnderlyingLinkProperties));
+                        }
                     } else if (exception.getCause() instanceof IOException) {
-                        errorCode = VpnManager.ERROR_CODE_NETWORK_IO;
+                        // TODO(b/230548427): Remove SDK check once VPN related stuff are
+                        //  decoupled from ConnectivityServiceTest.
+                        if (SdkLevel.isAtLeastT()) {
+                            sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_NETWORK_ERROR,
+                                    VpnManager.ERROR_CLASS_RECOVERABLE,
+                                    VpnManager.ERROR_CODE_NETWORK_IO,
+                                    getPackage(), mSessionKey, makeVpnProfileStateLocked(),
+                                    mActiveNetwork,
+                                    getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
+                                            mUnderlyingNetworkCapabilities),
+                                    getRedactedLinkPropertiesOfUnderlyingNetwork(
+                                            mUnderlyingLinkProperties));
+                        }
                     }
                 } else if (exception != null) {
                     Log.wtf(TAG, "onSessionLost: exception = " + exception);
                 }
-                // TODO(b/230548427): Remove SDK check once VPN related stuff are
-                //  decoupled from ConnectivityServiceTest.
-                if (SdkLevel.isAtLeastT()) {
-                    sendEventToVpnManagerApp(category, errorClass, errorCode,
-                            getPackage(), mSessionKey, makeVpnProfileStateLocked(),
-                            mActiveNetwork,
-                            getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
-                                    mUnderlyingNetworkCapabilities),
-                            getRedactedLinkPropertiesOfUnderlyingNetwork(
-                                    mUnderlyingLinkProperties));
-                }
-                if (errorClass == VpnManager.ERROR_CLASS_NOT_RECOVERABLE) {
-                    markFailedAndDisconnect(exception);
-                    return;
-                } else if (errorClass == VpnManager.ERROR_CLASS_RECOVERABLE) {
-                    // Retry a new IKE session.
-                }
             }
 
             mActiveNetwork = null;
diff --git a/services/core/java/com/android/server/testharness/OWNERS b/services/core/java/com/android/server/testharness/OWNERS
new file mode 100644
index 0000000..ffbbeb93
--- /dev/null
+++ b/services/core/java/com/android/server/testharness/OWNERS
@@ -0,0 +1 @@
+williamhester@google.com
diff --git a/services/core/java/com/android/server/testharness/TestHarnessModeService.java b/services/core/java/com/android/server/testharness/TestHarnessModeService.java
index 8b2b8b1..b6a4135 100644
--- a/services/core/java/com/android/server/testharness/TestHarnessModeService.java
+++ b/services/core/java/com/android/server/testharness/TestHarnessModeService.java
@@ -69,8 +69,8 @@
  * automatic updates, etc.) are all disabled by default but may be re-enabled by the user.
  */
 public class TestHarnessModeService extends SystemService {
+    public static final String TEST_HARNESS_MODE_PROPERTY = "persist.sys.test_harness";
     private static final String TAG = TestHarnessModeService.class.getSimpleName();
-    private static final String TEST_HARNESS_MODE_PROPERTY = "persist.sys.test_harness";
 
     private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal;
 
@@ -168,9 +168,9 @@
             Slog.d(TAG, "Restarted adbd");
         }
 
-        // Disable the TTL for ADB keys before enabling ADB
+        // Disable the TTL for ADB keys before ADB is enabled as a part of AdbService's
+        // initialization.
         Settings.Global.putLong(cr, Settings.Global.ADB_ALLOWED_CONNECTION_TIME, 0);
-        Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1);
         Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
         Settings.Global.putInt(cr, Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 0);
         Settings.Global.putInt(
diff --git a/services/core/java/com/android/server/wm/DisplayHashController.java b/services/core/java/com/android/server/wm/DisplayHashController.java
index 64a5758..543d4ad 100644
--- a/services/core/java/com/android/server/wm/DisplayHashController.java
+++ b/services/core/java/com/android/server/wm/DisplayHashController.java
@@ -369,9 +369,6 @@
             if (mServiceConnection == null) {
                 if (DEBUG) Slog.v(TAG, "creating connection");
 
-                // Create the connection
-                mServiceConnection = new DisplayHashingServiceConnection();
-
                 final ComponentName component = getServiceComponentName();
                 if (DEBUG) Slog.v(TAG, "binding to: " + component);
                 if (component != null) {
@@ -379,6 +376,8 @@
                     intent.setComponent(component);
                     final long token = Binder.clearCallingIdentity();
                     try {
+                        // Create the connection
+                        mServiceConnection = new DisplayHashingServiceConnection();
                         mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
                         if (DEBUG) Slog.v(TAG, "bound");
                     } finally {
@@ -387,7 +386,9 @@
                 }
             }
 
-            mServiceConnection.runCommandLocked(command);
+            if (mServiceConnection != null) {
+                mServiceConnection.runCommandLocked(command);
+            }
         }
     }
 
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 0c3f1dd..886a397 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -34,31 +34,19 @@
 // with dependencies moved to frameworks/libs/net right.
 java_library {
     name: "services.net-module-wifi",
-    srcs: [
-        ":framework-services-net-module-wifi-shared-srcs",
-        ":net-utils-services-common-srcs",
-    ],
     sdk_version: "module_current",
     min_sdk_version: "30",
-    libs: [
-        "framework-annotations-lib",
-        "unsupportedappusage",
-        "framework-wifi-util-lib",
-        "framework-connectivity",
-        "modules-utils-build_system",
-    ],
     static_libs: [
         // All the classes in netd_aidl_interface must be jarjar so they do not conflict with the
         // classes generated by netd_aidl_interfaces-platform-java above.
         "netd_aidl_interface-V3-java",
         "networkstack-client",
+        "net-utils-services-common",
     ],
     apex_available: [
         "com.android.wifi",
     ],
     visibility: [
-        "//frameworks/opt/net/wifi/service",
-        "//frameworks/opt/net/wifi/tests/wifitests",
         "//packages/modules/Wifi/service",
         "//packages/modules/Wifi/service/tests/wifitests",
     ],
diff --git a/services/tests/wmtests/OWNERS b/services/tests/wmtests/OWNERS
index 0862c05..7a128fc 100644
--- a/services/tests/wmtests/OWNERS
+++ b/services/tests/wmtests/OWNERS
@@ -1 +1,4 @@
 include /services/core/java/com/android/server/wm/OWNERS
+
+# Voice Interaction
+per-file *Assist* = file:/core/java/android/service/voice/OWNERS
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index f5047bf..00f27b5 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -787,11 +787,16 @@
             return;
         }
 
-        final File usageStatsDeDir = new File(Environment.getDataSystemDeDirectory(userId),
-                "usagestats");
-        if (!usageStatsDeDir.mkdirs() && !usageStatsDeDir.exists()) {
-            throw new IllegalStateException("Usage stats DE directory does not exist: "
-                    + usageStatsDeDir.getAbsolutePath());
+        final File deDir = Environment.getDataSystemDeDirectory(userId);
+        final File usageStatsDeDir = new File(deDir, "usagestats");
+        if (!usageStatsDeDir.mkdir() && !usageStatsDeDir.exists()) {
+            if (deDir.exists()) {
+                Slog.e(TAG, "Failed to create " + usageStatsDeDir);
+            } else {
+                Slog.w(TAG, "User " + userId + " was already removed! Discarding pending events");
+                pendingEvents.clear();
+            }
+            return;
         }
         final File pendingEventsFile = new File(usageStatsDeDir,
                 "pendingevents_" + System.currentTimeMillis());