Merge "Remove duplicated white space in ContextImpl when throw AndroidRuntimeException"
diff --git a/apct-tests/perftests/core/AndroidManifest.xml b/apct-tests/perftests/core/AndroidManifest.xml
index 56fa70c..0395480 100644
--- a/apct-tests/perftests/core/AndroidManifest.xml
+++ b/apct-tests/perftests/core/AndroidManifest.xml
@@ -15,6 +15,7 @@
 
     <application>
         <uses-library android:name="android.test.runner" />
+        <profileable android:shell="true" />
         <activity android:name="android.perftests.utils.PerfTestActivity"
             android:exported="true">
           <intent-filter>
diff --git a/api/Android.bp b/api/Android.bp
index 9fb7b35..505d7bf 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -38,23 +38,9 @@
     pluginFor: ["soong_build"],
 }
 
-python_defaults {
-    name: "python3_version_defaults",
-    version: {
-        py2: {
-            enabled: false,
-        },
-        py3: {
-            enabled: true,
-            embedded_launcher: false,
-        },
-    },
-}
-
 python_binary_host {
     name: "api_versions_trimmer",
     srcs: ["api_versions_trimmer.py"],
-    defaults: ["python3_version_defaults"],
 }
 
 python_test_host {
@@ -64,7 +50,6 @@
         "api_versions_trimmer_unittests.py",
         "api_versions_trimmer.py",
     ],
-    defaults: ["python3_version_defaults"],
     test_options: {
         unit_test: true,
     },
@@ -73,7 +58,6 @@
 python_binary_host {
     name: "merge_annotation_zips",
     srcs: ["merge_annotation_zips.py"],
-    defaults: ["python3_version_defaults"],
 }
 
 python_test_host {
@@ -83,7 +67,6 @@
         "merge_annotation_zips.py",
         "merge_annotation_zips_test.py",
     ],
-    defaults: ["python3_version_defaults"],
     test_options: {
         unit_test: true,
     },
diff --git a/api/Android.mk b/api/Android.mk
new file mode 100644
index 0000000..ce5f995
--- /dev/null
+++ b/api/Android.mk
@@ -0,0 +1,2 @@
+.PHONY: checkapi
+checkapi: frameworks-base-api-current-compat frameworks-base-api-system-current-compat frameworks-base-api-module-lib-current-compat
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 0126199..bb14dc0 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -10327,6 +10327,7 @@
     field public static final String NAMESPACE_LOCATION = "location";
     field public static final String NAMESPACE_MEDIA = "media";
     field public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
+    field public static final String NAMESPACE_NEARBY = "nearby";
     field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
     field public static final String NAMESPACE_NNAPI_NATIVE = "nnapi_native";
     field public static final String NAMESPACE_ON_DEVICE_PERSONALIZATION = "on_device_personalization";
diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java
index 3979c6c..10ce3bf 100644
--- a/core/java/android/net/Ikev2VpnProfile.java
+++ b/core/java/android/net/Ikev2VpnProfile.java
@@ -483,9 +483,6 @@
         final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */,
                 mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation,
                 mIkeTunConnParams);
-
-        profile.server = getServerAddr();
-        profile.ipsecIdentifier = getUserIdentity();
         profile.proxy = mProxyInfo;
         profile.isBypassable = mIsBypassable;
         profile.isMetered = mIsMetered;
@@ -499,6 +496,8 @@
         }
 
         profile.type = mType;
+        profile.server = getServerAddr();
+        profile.ipsecIdentifier = getUserIdentity();
         profile.setAllowedAlgorithms(mAllowedAlgorithms);
         switch (mType) {
             case TYPE_IKEV2_IPSEC_USER_PASS:
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index d403030..7b9ef72 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -203,6 +203,15 @@
     @SystemApi
     public static final String NAMESPACE_TETHERING = "tethering";
 
+
+    /**
+     * Namespace for Nearby module.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_NEARBY = "nearby";
+
     /**
      * Namespace for content capture feature used by on-device machine intelligence
      * to provide suggestions in a privacy-safe manner.
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index b1e7d15..deafd19 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -1001,16 +1001,24 @@
     }
 
     /**
+     * This will enable jdwp by default for all apps. It is OK to cache this property
+     * because we expect to reboot the system whenever this property changes
+     */
+    private static final boolean ENABLE_JDWP = SystemProperties.get(
+                          "persist.debug.dalvik.vm.jdwp.enabled").equals("1");
+
+    /**
      * Applies debugger system properties to the zygote arguments.
      *
-     * If "ro.debuggable" is "1", all apps are debuggable. Otherwise,
-     * the debugger state is specified via the "--enable-jdwp" flag
-     * in the spawn request.
+     * For eng builds all apps are debuggable. On userdebug and user builds
+     * if persist.debuggable.dalvik.vm.jdwp.enabled is 1 all apps are
+     * debuggable. Otherwise, the debugger state is specified via the
+     * "--enable-jdwp" flag in the spawn request.
      *
      * @param args non-null; zygote spawner args
      */
     static void applyDebuggerSystemProperty(ZygoteArguments args) {
-        if (RoSystemProperties.DEBUGGABLE) {
+        if (Build.IS_ENG || ENABLE_JDWP) {
             args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
         }
     }
diff --git a/core/java/com/android/internal/util/TypedProperties.java b/core/java/com/android/internal/util/TypedProperties.java
index 5613999..c10dbe7 100644
--- a/core/java/com/android/internal/util/TypedProperties.java
+++ b/core/java/com/android/internal/util/TypedProperties.java
@@ -264,29 +264,29 @@
             // Ensure that the type can hold this value, and return.
             int width = (type >> 8) & 0xff;
             switch (width) {
-            case 1:
-                if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
-                    throw new ParseException(st, "8-bit integer constant");
-                }
-                return new Byte((byte)value);
-            case 2:
-                if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
-                    throw new ParseException(st, "16-bit integer constant");
-                }
-                return new Short((short)value);
-            case 4:
-                if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
-                    throw new ParseException(st, "32-bit integer constant");
-                }
-                return new Integer((int)value);
-            case 8:
-                if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
-                    throw new ParseException(st, "64-bit integer constant");
-                }
-                return new Long(value);
-            default:
-                throw new IllegalStateException(
-                    "Internal error; unexpected integer type width " + width);
+                case 1:
+                    if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
+                        throw new ParseException(st, "8-bit integer constant");
+                    }
+                    return Byte.valueOf((byte) value);
+                case 2:
+                    if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
+                        throw new ParseException(st, "16-bit integer constant");
+                    }
+                    return Short.valueOf((short) value);
+                case 4:
+                    if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
+                        throw new ParseException(st, "32-bit integer constant");
+                    }
+                    return Integer.valueOf((int) value);
+                case 8:
+                    if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
+                        throw new ParseException(st, "64-bit integer constant");
+                    }
+                    return Long.valueOf(value);
+                default:
+                    throw new IllegalStateException(
+                            "Internal error; unexpected integer type width " + width);
             }
         } else if ((type & 0xff) == 'F') {
             if (token != StreamTokenizer.TT_WORD) {
@@ -317,10 +317,10 @@
                         throw new ParseException(st, "32-bit float constant");
                     }
                 }
-                return new Float((float)value);
+                return Float.valueOf((float) value);
             } else {
                 // This property is a double; no need to truncate.
-                return new Double(value);
+                return Double.valueOf(value);
             }
         } else if (type == TYPE_STRING) {
             // Expect a quoted string or the word "null".
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index f24c666..88aa4de 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2937,13 +2937,14 @@
 
     for (const auto &audioProfile : audioProfiles) {
         jobject jAudioProfile;
-        jStatus = convertAudioProfileFromNative(env, &jAudioProfile, &audioProfile, false);
-        if (jStatus == AUDIO_JAVA_BAD_VALUE) {
+        jint jConvertProfileStatus = convertAudioProfileFromNative(
+                                        env, &jAudioProfile, &audioProfile, false);
+        if (jConvertProfileStatus == AUDIO_JAVA_BAD_VALUE) {
             // skipping Java layer unsupported audio formats
             continue;
         }
-        if (jStatus != AUDIO_JAVA_SUCCESS) {
-            return jStatus;
+        if (jConvertProfileStatus != AUDIO_JAVA_SUCCESS) {
+            return jConvertProfileStatus;
         }
         env->CallBooleanMethod(jAudioProfilesList, gArrayListMethods.add, jAudioProfile);
         env->DeleteLocalRef(jAudioProfile);
diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp
index f7a98d1..30d9ea1 100644
--- a/core/jni/android_os_MessageQueue.cpp
+++ b/core/jni/android_os_MessageQueue.cpp
@@ -51,6 +51,21 @@
 
     virtual int handleEvent(int fd, int events, void* data);
 
+    /**
+     * A simple proxy that holds a weak reference to a looper callback.
+     */
+    class WeakLooperCallback : public LooperCallback {
+    protected:
+        virtual ~WeakLooperCallback();
+
+    public:
+        WeakLooperCallback(const wp<LooperCallback>& callback);
+        virtual int handleEvent(int fd, int events, void* data);
+
+    private:
+        wp<LooperCallback> mCallback;
+    };
+
 private:
     JNIEnv* mPollEnv;
     jobject mPollObj;
@@ -131,7 +146,8 @@
         if (events & CALLBACK_EVENT_OUTPUT) {
             looperEvents |= Looper::EVENT_OUTPUT;
         }
-        mLooper->addFd(fd, Looper::POLL_CALLBACK, looperEvents, this,
+        mLooper->addFd(fd, Looper::POLL_CALLBACK, looperEvents,
+                sp<WeakLooperCallback>::make(this),
                 reinterpret_cast<void*>(events));
     } else {
         mLooper->removeFd(fd);
@@ -162,6 +178,24 @@
 }
 
 
+// --- NativeMessageQueue::WeakLooperCallback ---
+
+NativeMessageQueue::WeakLooperCallback::WeakLooperCallback(const wp<LooperCallback>& callback) :
+        mCallback(callback) {
+}
+
+NativeMessageQueue::WeakLooperCallback::~WeakLooperCallback() {
+}
+
+int NativeMessageQueue::WeakLooperCallback::handleEvent(int fd, int events, void* data) {
+    sp<LooperCallback> callback = mCallback.promote();
+    if (callback != nullptr) {
+        return callback->handleEvent(fd, events, data);
+    }
+    return 0;
+}
+
+
 // ----------------------------------------------------------------------------
 
 sp<MessageQueue> android_os_MessageQueue_getMessageQueue(JNIEnv* env, jobject messageQueueObj) {
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 676dc19..6a53978 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -3210,41 +3210,44 @@
                 return;
             }
 
-            if (mSession != null && mMobikeEnabled) {
-                Log.d(
-                        TAG,
-                        "IKE Session has mobility. Delay handleSessionLost for losing network "
-                                + network
-                                + " on session with token "
-                                + mCurrentToken);
+            Log.d(TAG, "Schedule a delay handleSessionLost for losing network "
+                            + network
+                            + " on session with token "
+                            + mCurrentToken);
 
-                final int token = mCurrentToken;
-                // Delay the teardown in case a new network will be available soon. For example,
-                // during handover between two WiFi networks, Android will disconnect from the
-                // first WiFi and then connects to the second WiFi.
-                mScheduledHandleNetworkLostFuture =
-                        mExecutor.schedule(
-                                () -> {
-                                    if (isActiveToken(token)) {
-                                        handleSessionLost(null /* exception */, network);
-                                    } else {
-                                        Log.d(
-                                                TAG,
-                                                "Scheduled handleSessionLost fired for "
-                                                        + "obsolete token "
-                                                        + token);
+            final int token = mCurrentToken;
+            // Delay the teardown in case a new network will be available soon. For example,
+            // during handover between two WiFi networks, Android will disconnect from the
+            // first WiFi and then connects to the second WiFi.
+            mScheduledHandleNetworkLostFuture =
+                    mExecutor.schedule(
+                            () -> {
+                                if (isActiveToken(token)) {
+                                    handleSessionLost(new IkeNetworkLostException(network),
+                                            network);
+
+                                    synchronized (Vpn.this) {
+                                        // Ignore stale runner.
+                                        if (mVpnRunner != this) return;
+
+                                        updateState(DetailedState.DISCONNECTED,
+                                                "Network lost");
                                     }
+                                } else {
+                                    Log.d(
+                                            TAG,
+                                            "Scheduled handleSessionLost fired for "
+                                                    + "obsolete token "
+                                                    + token);
+                                }
 
-                                    // Reset mScheduledHandleNetworkLostFuture since it's
-                                    // already run on executor thread.
-                                    mScheduledHandleNetworkLostFuture = null;
-                                },
-                                NETWORK_LOST_TIMEOUT_MS,
-                                TimeUnit.MILLISECONDS);
-            } else {
-                Log.d(TAG, "Call handleSessionLost for losing network " + network);
-                handleSessionLost(null /* exception */, network);
-            }
+                                // Reset mScheduledHandleNetworkLostFuture since it's
+                                // already run on executor thread.
+                                mScheduledHandleNetworkLostFuture = null;
+                            },
+                            NETWORK_LOST_TIMEOUT_MS,
+                            TimeUnit.MILLISECONDS);
+
         }
 
         private void cancelHandleNetworkLostTimeout() {
@@ -4185,8 +4188,6 @@
      */
     @NonNull
     public synchronized List<String> getAppExclusionList(@NonNull String packageName) {
-        enforceNotRestrictedUser();
-
         final long oldId = Binder.clearCallingIdentity();
         try {
             final byte[] bytes = getVpnProfileStore().get(getVpnAppExcludedForPackage(packageName));
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 99bbc3f..32ff5e22 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -71,6 +71,9 @@
     private static final String TAG = "HdmiCecLocalDeviceAudioSystem";
 
     private static final boolean WAKE_ON_HOTPLUG = false;
+    private static final int MAX_CHANNELS = 8;
+    private static final HashMap<Integer, List<Integer>> AUDIO_CODECS_MAP =
+            mapAudioCodecWithAudioFormat();
 
     // Whether the System Audio Control feature is enabled or not. True by default.
     @GuardedBy("mLock")
@@ -485,17 +488,17 @@
             }
         }
 
-        @AudioCodec int[] audioFormatCodes = parseAudioFormatCodes(message.getParams());
+        @AudioCodec int[] audioCodecs = parseAudioCodecs(message.getParams());
         byte[] sadBytes;
         if (config != null && config.size() > 0) {
-            sadBytes = getSupportedShortAudioDescriptorsFromConfig(config, audioFormatCodes);
+            sadBytes = getSupportedShortAudioDescriptorsFromConfig(config, audioCodecs);
         } else {
             AudioDeviceInfo deviceInfo = getSystemAudioDeviceInfo();
             if (deviceInfo == null) {
                 return Constants.ABORT_UNABLE_TO_DETERMINE;
             }
 
-            sadBytes = getSupportedShortAudioDescriptors(deviceInfo, audioFormatCodes);
+            sadBytes = getSupportedShortAudioDescriptors(deviceInfo, audioCodecs);
         }
 
         if (sadBytes.length == 0) {
@@ -508,11 +511,12 @@
         }
     }
 
-    private byte[] getSupportedShortAudioDescriptors(
-            AudioDeviceInfo deviceInfo, @AudioCodec int[] audioFormatCodes) {
-        ArrayList<byte[]> sads = new ArrayList<>(audioFormatCodes.length);
-        for (@AudioCodec int audioFormatCode : audioFormatCodes) {
-            byte[] sad = getSupportedShortAudioDescriptor(deviceInfo, audioFormatCode);
+    @VisibleForTesting
+    byte[] getSupportedShortAudioDescriptors(
+            AudioDeviceInfo deviceInfo, @AudioCodec int[] audioCodecs) {
+        ArrayList<byte[]> sads = new ArrayList<>(audioCodecs.length);
+        for (@AudioCodec int audioCodec : audioCodecs) {
+            byte[] sad = getSupportedShortAudioDescriptor(deviceInfo, audioCodec);
             if (sad != null) {
                 if (sad.length == 3) {
 
@@ -520,7 +524,7 @@
                 } else {
                     HdmiLogger.warning(
                             "Dropping Short Audio Descriptor with length %d for requested codec %x",
-                            sad.length, audioFormatCode);
+                            sad.length, audioCodec);
                 }
             }
         }
@@ -528,7 +532,7 @@
     }
 
     private byte[] getSupportedShortAudioDescriptorsFromConfig(
-            List<DeviceConfig> deviceConfig, @AudioCodec int[] audioFormatCodes) {
+            List<DeviceConfig> deviceConfig, @AudioCodec int[] audioCodecs) {
         DeviceConfig deviceConfigToUse = null;
         String audioDeviceName = SystemProperties.get(
                 Constants.PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT,
@@ -544,13 +548,13 @@
             return new byte[0];
         }
         HashMap<Integer, byte[]> map = new HashMap<>();
-        ArrayList<byte[]> sads = new ArrayList<>(audioFormatCodes.length);
+        ArrayList<byte[]> sads = new ArrayList<>(audioCodecs.length);
         for (CodecSad codecSad : deviceConfigToUse.supportedCodecs) {
             map.put(codecSad.audioCodec, codecSad.sad);
         }
-        for (int i = 0; i < audioFormatCodes.length; i++) {
-            if (map.containsKey(audioFormatCodes[i])) {
-                byte[] sad = map.get(audioFormatCodes[i]);
+        for (int i = 0; i < audioCodecs.length; i++) {
+            if (map.containsKey(audioCodecs[i])) {
+                byte[] sad = map.get(audioCodecs[i]);
                 if (sad != null && sad.length == 3) {
                     sads.add(sad);
                 }
@@ -572,42 +576,171 @@
 
     /**
      * Returns a 3 byte short audio descriptor as described in CEC 1.4 table 29 or null if the
-     * audioFormatCode is not supported.
+     * audioCodec is not supported.
      */
     @Nullable
-    private byte[] getSupportedShortAudioDescriptor(
-            AudioDeviceInfo deviceInfo, @AudioCodec int audioFormatCode) {
-        switch (audioFormatCode) {
-            case Constants.AUDIO_CODEC_NONE: {
-                return null;
-            }
-            case Constants.AUDIO_CODEC_LPCM: {
-                return getLpcmShortAudioDescriptor(deviceInfo);
-            }
-            // TODO(b/80297701): implement the rest of the codecs
-            case Constants.AUDIO_CODEC_DD:
-            case Constants.AUDIO_CODEC_MPEG1:
-            case Constants.AUDIO_CODEC_MP3:
-            case Constants.AUDIO_CODEC_MPEG2:
-            case Constants.AUDIO_CODEC_AAC:
-            case Constants.AUDIO_CODEC_DTS:
-            case Constants.AUDIO_CODEC_ATRAC:
-            case Constants.AUDIO_CODEC_ONEBITAUDIO:
-            case Constants.AUDIO_CODEC_DDP:
-            case Constants.AUDIO_CODEC_DTSHD:
-            case Constants.AUDIO_CODEC_TRUEHD:
-            case Constants.AUDIO_CODEC_DST:
-            case Constants.AUDIO_CODEC_WMAPRO:
-            default: {
-                return null;
+    @VisibleForTesting
+    byte[] getSupportedShortAudioDescriptor(
+            AudioDeviceInfo deviceInfo, @AudioCodec int audioCodec) {
+        byte[] shortAudioDescriptor = new byte[3];
+
+        int[] deviceSupportedAudioFormats = deviceInfo.getEncodings();
+        // Return null when audioCodec or device does not support any audio formats.
+        if (!AUDIO_CODECS_MAP.containsKey(audioCodec) || deviceSupportedAudioFormats.length == 0) {
+            return null;
+        }
+        List<Integer> audioCodecSupportedAudioFormats = AUDIO_CODECS_MAP.get(audioCodec);
+
+        for (int supportedAudioFormat : deviceSupportedAudioFormats) {
+            if (audioCodecSupportedAudioFormats.contains(supportedAudioFormat)) {
+                // Initialise the first two bytes of short audio descriptor.
+                shortAudioDescriptor[0] = getFirstByteOfSAD(deviceInfo, audioCodec);
+                shortAudioDescriptor[1] = getSecondByteOfSAD(deviceInfo);
+                switch (audioCodec) {
+                    case Constants.AUDIO_CODEC_NONE: {
+                        return null;
+                    }
+                    case Constants.AUDIO_CODEC_LPCM: {
+                        if (supportedAudioFormat == AudioFormat.ENCODING_PCM_16BIT) {
+                            shortAudioDescriptor[2] = (byte) 0x01;
+                        } else if (supportedAudioFormat
+                                == AudioFormat.ENCODING_PCM_24BIT_PACKED) {
+                            shortAudioDescriptor[2] = (byte) 0x04;
+                        } else {
+                            // Since no bit is reserved for these audio formats in LPCM codec.
+                            shortAudioDescriptor[2] = (byte) 0x00;
+                        }
+                        return shortAudioDescriptor;
+                    }
+                    case Constants.AUDIO_CODEC_DD:
+                    case Constants.AUDIO_CODEC_MPEG1:
+                    case Constants.AUDIO_CODEC_MP3:
+                    case Constants.AUDIO_CODEC_MPEG2:
+                    case Constants.AUDIO_CODEC_AAC:
+                    case Constants.AUDIO_CODEC_DTS: {
+                        shortAudioDescriptor[2] = getThirdSadByteForCodecs2Through8(deviceInfo);
+                        return shortAudioDescriptor;
+                    }
+                    case Constants.AUDIO_CODEC_DDP:
+                    case Constants.AUDIO_CODEC_DTSHD:
+                    case Constants.AUDIO_CODEC_TRUEHD: {
+                        // Default value is 0x0 unless defined by Audio Codec Vendor.
+                        shortAudioDescriptor[2] = (byte) 0x00;
+                        return shortAudioDescriptor;
+                    }
+                    case Constants.AUDIO_CODEC_ATRAC:
+                    case Constants.AUDIO_CODEC_ONEBITAUDIO:
+                    case Constants.AUDIO_CODEC_DST:
+                    case Constants.AUDIO_CODEC_WMAPRO:
+                        // Not supported.
+                    default: {
+                        return null;
+                    }
+                }
             }
         }
+        return null;
     }
 
-    @Nullable
-    private byte[] getLpcmShortAudioDescriptor(AudioDeviceInfo deviceInfo) {
-        // TODO(b/80297701): implement
-        return null;
+    private static HashMap<Integer, List<Integer>> mapAudioCodecWithAudioFormat() {
+        // Mapping the values of @AudioCodec audio codecs with @AudioFormat audio formats.
+        HashMap<Integer, List<Integer>> audioCodecsMap = new HashMap<Integer, List<Integer>>();
+
+        audioCodecsMap.put(Constants.AUDIO_CODEC_NONE, List.of(AudioFormat.ENCODING_DEFAULT));
+        audioCodecsMap.put(
+                Constants.AUDIO_CODEC_LPCM,
+                List.of(
+                        AudioFormat.ENCODING_PCM_8BIT,
+                        AudioFormat.ENCODING_PCM_16BIT,
+                        AudioFormat.ENCODING_PCM_FLOAT,
+                        AudioFormat.ENCODING_PCM_24BIT_PACKED,
+                        AudioFormat.ENCODING_PCM_32BIT));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_DD, List.of(AudioFormat.ENCODING_AC3));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_MPEG1, List.of(AudioFormat.ENCODING_AAC_HE_V1));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_MPEG2, List.of(AudioFormat.ENCODING_AAC_HE_V2));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_MP3, List.of(AudioFormat.ENCODING_MP3));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_AAC, List.of(AudioFormat.ENCODING_AAC_LC));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_DTS, List.of(AudioFormat.ENCODING_DTS));
+        audioCodecsMap.put(
+                Constants.AUDIO_CODEC_DDP,
+                List.of(AudioFormat.ENCODING_E_AC3, AudioFormat.ENCODING_E_AC3_JOC));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_DTSHD, List.of(AudioFormat.ENCODING_DTS_HD));
+        audioCodecsMap.put(
+                Constants.AUDIO_CODEC_TRUEHD,
+                List.of(AudioFormat.ENCODING_DOLBY_TRUEHD, AudioFormat.ENCODING_DOLBY_MAT));
+
+        return audioCodecsMap;
+    }
+
+    private byte getFirstByteOfSAD(AudioDeviceInfo deviceInfo, @AudioCodec int audioCodec) {
+        byte firstByte = 0;
+        int maxNumberOfChannels = getMaxNumberOfChannels(deviceInfo);
+
+        // Fill bits 0-2 of the first byte.
+        firstByte |= (maxNumberOfChannels - 1);
+
+        // Fill bits 3-6 of the first byte.
+        firstByte |= (audioCodec << 3);
+
+        return firstByte;
+    }
+
+    private byte getSecondByteOfSAD(AudioDeviceInfo deviceInfo) {
+        ArrayList<Integer> samplingRates =
+                new ArrayList<Integer>(Arrays.asList(32, 44, 48, 88, 96, 176, 192));
+
+        // samplingRatesdevicesupports is guaranteed to be not null
+        int[] samplingRatesDeviceSupports = deviceInfo.getSampleRates();
+        if (samplingRatesDeviceSupports.length == 0) {
+            Slog.e(TAG, "Device supports arbitrary rates");
+            // Since device supports arbitrary rates, we will return 0x7f since bit 7 is reserved.
+            return (byte) 0x7f;
+        }
+        byte secondByte = 0;
+        for (int supportedSampleRate : samplingRatesDeviceSupports) {
+            if (samplingRates.contains(supportedSampleRate)) {
+                int index = samplingRates.indexOf(supportedSampleRate);
+                // Setting the bit of a sample rate which is being supported.
+                secondByte |= (1 << index);
+            }
+        }
+
+        return secondByte;
+    }
+
+    /**
+     * Empty array from deviceInfo.getChannelCounts() implies device supports arbitrary channel
+     * counts and hence we assume max channels are supported by the device.
+     */
+    private int getMaxNumberOfChannels(AudioDeviceInfo deviceInfo) {
+        int maxNumberOfChannels = MAX_CHANNELS;
+        int[] channelCounts = deviceInfo.getChannelCounts();
+        if (channelCounts.length != 0) {
+            maxNumberOfChannels = channelCounts[channelCounts.length - 1];
+            maxNumberOfChannels =
+                    (maxNumberOfChannels > MAX_CHANNELS ? MAX_CHANNELS : maxNumberOfChannels);
+        }
+        return maxNumberOfChannels;
+    }
+
+    private byte getThirdSadByteForCodecs2Through8(AudioDeviceInfo deviceInfo) {
+        /*
+         * Here, we are assuming that max bit rate is closely equals to the max sampling rate the
+         * device supports.
+         */
+        int maxSamplingRate = 0;
+        int[] samplingRatesDeviceSupports = deviceInfo.getSampleRates();
+        if (samplingRatesDeviceSupports.length == 0) {
+            maxSamplingRate = 192;
+        } else {
+            for (int sampleRate : samplingRatesDeviceSupports) {
+                if (maxSamplingRate < sampleRate) {
+                    maxSamplingRate = sampleRate;
+                }
+            }
+        }
+
+        return (byte) (maxSamplingRate / 8);
     }
 
     @Nullable
@@ -634,14 +767,14 @@
     }
 
     @AudioCodec
-    private int[] parseAudioFormatCodes(byte[] params) {
-        @AudioCodec int[] audioFormatCodes = new int[params.length];
+    private int[] parseAudioCodecs(byte[] params) {
+        @AudioCodec int[] audioCodecs = new int[params.length];
         for (int i = 0; i < params.length; i++) {
             byte val = params[i];
-            audioFormatCodes[i] =
-                val >= 1 && val <= Constants.AUDIO_CODEC_MAX ? val : Constants.AUDIO_CODEC_NONE;
+            audioCodecs[i] =
+                    val >= 1 && val <= Constants.AUDIO_CODEC_MAX ? val : Constants.AUDIO_CODEC_NONE;
         }
-        return audioFormatCodes;
+        return audioCodecs;
     }
 
     @Override
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index c75de42..ac892da 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -265,7 +265,7 @@
     /** @hide */
     @Override
     public void onDestroy() {
-        mHandlerThread.quit();
+        mHandlerThread.quitSafely();
         super.onDestroy();
     }
 
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index 700d615..d8b2cbe 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -725,7 +725,7 @@
 
     @Override
     public void onDestroy() {
-        mHandlerThread.quit();
+        mHandlerThread.quitSafely();
         super.onDestroy();
     }
 
diff --git a/tools/fonts/Android.bp b/tools/fonts/Android.bp
index eeb9e3c..f8629f9 100644
--- a/tools/fonts/Android.bp
+++ b/tools/fonts/Android.bp
@@ -24,12 +24,7 @@
 python_defaults {
     name: "fonts_python_defaults",
     version: {
-        py2: {
-            enabled: false,
-            embedded_launcher: false,
-        },
         py3: {
-            enabled: true,
             embedded_launcher: true,
         },
     },