Merge "Update language to comply with Android's inclusive language guidance"
diff --git a/Android.bp b/Android.bp
index a93a155..8e2f0ec 100644
--- a/Android.bp
+++ b/Android.bp
@@ -456,6 +456,7 @@
 
         "com.android.sysprop.apex",
         "com.android.sysprop.init",
+        "com.android.sysprop.localization",
         "PlatformProperties",
     ],
     sdk_version: "core_platform",
diff --git a/api/current.txt b/api/current.txt
index 8dd7af8..ed9fba7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -43556,6 +43556,7 @@
 package android.telecom {
 
   public final class Call {
+    method public void addConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
     method public void answer(int);
     method public void conference(android.telecom.Call);
     method public void deflect(android.net.Uri);
@@ -43664,6 +43665,7 @@
     method public static boolean hasProperty(int, int);
     method public boolean hasProperty(int);
     method public static String propertiesToString(int);
+    field public static final int CAPABILITY_ADD_PARTICIPANT = 33554432; // 0x2000000
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_CAN_PULL_CALL = 8388608; // 0x800000
@@ -43693,6 +43695,7 @@
     field public static final int PROPERTY_GENERIC_CONFERENCE = 2; // 0x2
     field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 128; // 0x80
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
+    field public static final int PROPERTY_IS_ADHOC_CONFERENCE = 8192; // 0x2000
     field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
     field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 2048; // 0x800
     field public static final int PROPERTY_RTT = 1024; // 0x400
@@ -43770,6 +43773,7 @@
   public abstract class Conference extends android.telecom.Conferenceable {
     ctor public Conference(android.telecom.PhoneAccountHandle);
     method public final boolean addConnection(android.telecom.Connection);
+    method @NonNull public static android.telecom.Conference createFailedConference(@NonNull android.telecom.DisconnectCause, @NonNull android.telecom.PhoneAccountHandle);
     method public final void destroy();
     method public final android.telecom.CallAudioState getCallAudioState();
     method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
@@ -43785,6 +43789,9 @@
     method public final android.telecom.StatusHints getStatusHints();
     method public android.telecom.Connection.VideoProvider getVideoProvider();
     method public int getVideoState();
+    method public final boolean isRingbackRequested();
+    method public void onAddConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
+    method public void onAnswer(int);
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onConnectionAdded(android.telecom.Connection);
     method public void onDisconnect();
@@ -43793,6 +43800,7 @@
     method public void onMerge(android.telecom.Connection);
     method public void onMerge();
     method public void onPlayDtmfTone(char);
+    method public void onReject();
     method public void onSeparate(android.telecom.Connection);
     method public void onStopDtmfTone();
     method public void onSwap();
@@ -43813,6 +43821,8 @@
     method public final void setDisconnected(android.telecom.DisconnectCause);
     method public final void setExtras(@Nullable android.os.Bundle);
     method public final void setOnHold();
+    method public final void setRingbackRequested(boolean);
+    method public final void setRinging();
     method public final void setStatusHints(android.telecom.StatusHints);
     method public final void setVideoProvider(android.telecom.Connection, android.telecom.Connection.VideoProvider);
     method public final void setVideoState(android.telecom.Connection, int);
@@ -43849,6 +43859,7 @@
     method public final boolean isRingbackRequested();
     method public final void notifyConferenceMergeFailed();
     method public void onAbort();
+    method public void onAddConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
     method public void onAnswer(int);
     method public void onAnswer();
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
@@ -43928,6 +43939,7 @@
     field public static final int AUDIO_CODEC_GSM_HR = 10; // 0xa
     field public static final int AUDIO_CODEC_NONE = 0; // 0x0
     field public static final int AUDIO_CODEC_QCELP13K = 3; // 0x3
+    field public static final int CAPABILITY_ADD_PARTICIPANT = 67108864; // 0x4000000
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
@@ -43971,6 +43983,7 @@
     field public static final int PROPERTY_ASSISTED_DIALING = 512; // 0x200
     field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 32; // 0x20
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 4; // 0x4
+    field public static final int PROPERTY_IS_ADHOC_CONFERENCE = 4096; // 0x1000
     field public static final int PROPERTY_IS_EXTERNAL_CALL = 16; // 0x10
     field public static final int PROPERTY_IS_RTT = 256; // 0x100
     field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1024; // 0x400
@@ -44066,9 +44079,13 @@
     method public void onConference(android.telecom.Connection, android.telecom.Connection);
     method public void onConnectionServiceFocusGained();
     method public void onConnectionServiceFocusLost();
+    method @Nullable public android.telecom.Conference onCreateIncomingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
+    method public void onCreateIncomingConferenceFailed(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateIncomingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method @Nullable public android.telecom.Conference onCreateOutgoingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
+    method public void onCreateOutgoingConferenceFailed(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateOutgoingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
@@ -44379,6 +44396,7 @@
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall(int);
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
+    method public void addNewIncomingConference(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void cancelMissedCallsNotification();
     method public android.content.Intent createManageBlockedNumbersIntent();
     method @Deprecated @RequiresPermission(android.Manifest.permission.ANSWER_PHONE_CALLS) public boolean endCall();
@@ -44406,6 +44424,7 @@
     method public void registerPhoneAccount(android.telecom.PhoneAccount);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void showInCallScreen(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void silenceRinger();
+    method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void startConference(@NonNull java.util.List<android.net.Uri>, @NonNull android.os.Bundle);
     method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
     field public static final String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
     field public static final String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
@@ -44943,6 +44962,8 @@
     field public static final String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
     field public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
     field public static final String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool";
+    field public static final String KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL = "support_add_conference_participants_bool";
+    field public static final String KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL = "support_adhoc_conference_calls_bool";
     field public static final String KEY_SUPPORT_CLIR_NETWORK_DEFAULT_BOOL = "support_clir_network_default_bool";
     field public static final String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
     field public static final String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index 37ee859..cacc950 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -55,5 +55,10 @@
     method public final void markVintfStability();
   }
 
+  public interface Parcelable {
+    field public static final int PARCELABLE_STABILITY_LOCAL = 0; // 0x0
+    field public static final int PARCELABLE_STABILITY_VINTF = 1; // 0x1
+  }
+
 }
 
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index c8f2efa..7745677 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -60,7 +60,7 @@
 import "frameworks/base/core/proto/android/wifi/enums.proto";
 
 /**
- * The master atom class. This message defines all of the available
+ * The primary atom class. This message defines all of the available
  * raw stats log events from the Android system, also known as "atoms."
  *
  * This field contains a single oneof with all of the available messages.
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index 3439e89..13d251a 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -57,7 +57,7 @@
 }
 
 void ConfigManager::StartupForTest() {
-    // Dummy function to avoid reading configs from disks for tests.
+    // No-op function to avoid reading configs from disks for tests.
 }
 
 void ConfigManager::AddListener(const sp<ConfigListener>& listener) {
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
index dc57f2d..1fdec31 100644
--- a/cmds/statsd/src/config/ConfigManager.h
+++ b/cmds/statsd/src/config/ConfigManager.h
@@ -44,7 +44,7 @@
     void Startup();
 
     /*
-     * Dummy initializer for tests.
+     * No-op initializer for tests.
      */
     void StartupForTest();
 
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
index 2b9528f..2cbcf28 100644
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp
@@ -18,9 +18,6 @@
 #include "stats_util.h"
 
 #include <gtest/gtest.h>
-#include <log/log_event_list.h>
-#include <log/log_read.h>
-#include <log/logprint.h>
 
 #include <stdio.h>
 
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index 35f4add..24d65fb 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -65,6 +65,7 @@
     private static final String COMMAND_SET_DEFAULT_DIALER = "set-default-dialer";
     private static final String COMMAND_GET_DEFAULT_DIALER = "get-default-dialer";
     private static final String COMMAND_STOP_BLOCK_SUPPRESSION = "stop-block-suppression";
+    private static final String COMMAND_CLEANUP_STUCK_CALLS = "cleanup-stuck-calls";
 
     /**
      * Change the system dialer package name if a package name was specified,
@@ -115,6 +116,8 @@
                 + "usage: telecom get-max-phones\n"
                 + "usage: telecom stop-block-suppression: Stop suppressing the blocked number"
                         + " provider after a call to emergency services.\n"
+                + "usage: telecom cleanup-stuck-calls: Clear any disconnected calls that have"
+                + " gotten wedged in Telecom.\n"
                 + "usage: telecom set-emer-phone-account-filter <PACKAGE>\n"
                 + "\n"
                 + "telecom set-phone-account-enabled: Enables the given phone account, if it has"
@@ -210,6 +213,9 @@
             case COMMAND_STOP_BLOCK_SUPPRESSION:
                 runStopBlockSuppression();
                 break;
+            case COMMAND_CLEANUP_STUCK_CALLS:
+                runCleanupStuckCalls();
+                break;
             case COMMAND_SET_DEFAULT_DIALER:
                 runSetDefaultDialer();
                 break;
@@ -331,6 +337,10 @@
         mTelecomService.stopBlockSuppression();
     }
 
+    private void runCleanupStuckCalls() throws RemoteException {
+        mTelecomService.cleanupStuckCalls();
+    }
+
     private void runSetDefaultDialer() throws RemoteException {
         String packageName = nextArg();
         if ("default".equals(packageName)) packageName = null;
diff --git a/cmds/uiautomator/api/current.txt b/cmds/uiautomator/api/current.txt
index 489c2ea..bf87d09 100644
--- a/cmds/uiautomator/api/current.txt
+++ b/cmds/uiautomator/api/current.txt
@@ -1,221 +1,222 @@
+// Signature format: 2.0
 package com.android.uiautomator.core {
 
-  public final deprecated class Configurator {
-    method public long getActionAcknowledgmentTimeout();
-    method public static com.android.uiautomator.core.Configurator getInstance();
-    method public long getKeyInjectionDelay();
-    method public long getScrollAcknowledgmentTimeout();
-    method public long getWaitForIdleTimeout();
-    method public long getWaitForSelectorTimeout();
-    method public com.android.uiautomator.core.Configurator setActionAcknowledgmentTimeout(long);
-    method public com.android.uiautomator.core.Configurator setKeyInjectionDelay(long);
-    method public com.android.uiautomator.core.Configurator setScrollAcknowledgmentTimeout(long);
-    method public com.android.uiautomator.core.Configurator setWaitForIdleTimeout(long);
-    method public com.android.uiautomator.core.Configurator setWaitForSelectorTimeout(long);
+  @Deprecated public final class Configurator {
+    method @Deprecated public long getActionAcknowledgmentTimeout();
+    method @Deprecated public static com.android.uiautomator.core.Configurator getInstance();
+    method @Deprecated public long getKeyInjectionDelay();
+    method @Deprecated public long getScrollAcknowledgmentTimeout();
+    method @Deprecated public long getWaitForIdleTimeout();
+    method @Deprecated public long getWaitForSelectorTimeout();
+    method @Deprecated public com.android.uiautomator.core.Configurator setActionAcknowledgmentTimeout(long);
+    method @Deprecated public com.android.uiautomator.core.Configurator setKeyInjectionDelay(long);
+    method @Deprecated public com.android.uiautomator.core.Configurator setScrollAcknowledgmentTimeout(long);
+    method @Deprecated public com.android.uiautomator.core.Configurator setWaitForIdleTimeout(long);
+    method @Deprecated public com.android.uiautomator.core.Configurator setWaitForSelectorTimeout(long);
   }
 
-  public deprecated class UiCollection extends com.android.uiautomator.core.UiObject {
-    ctor public UiCollection(com.android.uiautomator.core.UiSelector);
-    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public com.android.uiautomator.core.UiObject getChildByInstance(com.android.uiautomator.core.UiSelector, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public int getChildCount(com.android.uiautomator.core.UiSelector);
+  @Deprecated public class UiCollection extends com.android.uiautomator.core.UiObject {
+    ctor @Deprecated public UiCollection(com.android.uiautomator.core.UiSelector);
+    method @Deprecated public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public com.android.uiautomator.core.UiObject getChildByInstance(com.android.uiautomator.core.UiSelector, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public int getChildCount(com.android.uiautomator.core.UiSelector);
   }
 
-  public deprecated class UiDevice {
-    method public void clearLastTraversedText();
-    method public boolean click(int, int);
-    method public boolean drag(int, int, int, int, int);
-    method public void dumpWindowHierarchy(java.lang.String);
-    method public void freezeRotation() throws android.os.RemoteException;
-    method public deprecated java.lang.String getCurrentActivityName();
-    method public java.lang.String getCurrentPackageName();
-    method public int getDisplayHeight();
-    method public int getDisplayRotation();
-    method public android.graphics.Point getDisplaySizeDp();
-    method public int getDisplayWidth();
-    method public static com.android.uiautomator.core.UiDevice getInstance();
-    method public java.lang.String getLastTraversedText();
-    method public java.lang.String getProductName();
-    method public boolean hasAnyWatcherTriggered();
-    method public boolean hasWatcherTriggered(java.lang.String);
-    method public boolean isNaturalOrientation();
-    method public boolean isScreenOn() throws android.os.RemoteException;
-    method public boolean openNotification();
-    method public boolean openQuickSettings();
-    method public boolean pressBack();
-    method public boolean pressDPadCenter();
-    method public boolean pressDPadDown();
-    method public boolean pressDPadLeft();
-    method public boolean pressDPadRight();
-    method public boolean pressDPadUp();
-    method public boolean pressDelete();
-    method public boolean pressEnter();
-    method public boolean pressHome();
-    method public boolean pressKeyCode(int);
-    method public boolean pressKeyCode(int, int);
-    method public boolean pressMenu();
-    method public boolean pressRecentApps() throws android.os.RemoteException;
-    method public boolean pressSearch();
-    method public void registerWatcher(java.lang.String, com.android.uiautomator.core.UiWatcher);
-    method public void removeWatcher(java.lang.String);
-    method public void resetWatcherTriggers();
-    method public void runWatchers();
-    method public void setCompressedLayoutHeirarchy(boolean);
-    method public void setOrientationLeft() throws android.os.RemoteException;
-    method public void setOrientationNatural() throws android.os.RemoteException;
-    method public void setOrientationRight() throws android.os.RemoteException;
-    method public void sleep() throws android.os.RemoteException;
-    method public boolean swipe(int, int, int, int, int);
-    method public boolean swipe(android.graphics.Point[], int);
-    method public boolean takeScreenshot(java.io.File);
-    method public boolean takeScreenshot(java.io.File, float, int);
-    method public void unfreezeRotation() throws android.os.RemoteException;
-    method public void waitForIdle();
-    method public void waitForIdle(long);
-    method public boolean waitForWindowUpdate(java.lang.String, long);
-    method public void wakeUp() throws android.os.RemoteException;
+  @Deprecated public class UiDevice {
+    method @Deprecated public void clearLastTraversedText();
+    method @Deprecated public boolean click(int, int);
+    method @Deprecated public boolean drag(int, int, int, int, int);
+    method @Deprecated public void dumpWindowHierarchy(String);
+    method @Deprecated public void freezeRotation() throws android.os.RemoteException;
+    method @Deprecated public String getCurrentActivityName();
+    method @Deprecated public String getCurrentPackageName();
+    method @Deprecated public int getDisplayHeight();
+    method @Deprecated public int getDisplayRotation();
+    method @Deprecated public android.graphics.Point getDisplaySizeDp();
+    method @Deprecated public int getDisplayWidth();
+    method @Deprecated public static com.android.uiautomator.core.UiDevice getInstance();
+    method @Deprecated public String getLastTraversedText();
+    method @Deprecated public String getProductName();
+    method @Deprecated public boolean hasAnyWatcherTriggered();
+    method @Deprecated public boolean hasWatcherTriggered(String);
+    method @Deprecated public boolean isNaturalOrientation();
+    method @Deprecated public boolean isScreenOn() throws android.os.RemoteException;
+    method @Deprecated public boolean openNotification();
+    method @Deprecated public boolean openQuickSettings();
+    method @Deprecated public boolean pressBack();
+    method @Deprecated public boolean pressDPadCenter();
+    method @Deprecated public boolean pressDPadDown();
+    method @Deprecated public boolean pressDPadLeft();
+    method @Deprecated public boolean pressDPadRight();
+    method @Deprecated public boolean pressDPadUp();
+    method @Deprecated public boolean pressDelete();
+    method @Deprecated public boolean pressEnter();
+    method @Deprecated public boolean pressHome();
+    method @Deprecated public boolean pressKeyCode(int);
+    method @Deprecated public boolean pressKeyCode(int, int);
+    method @Deprecated public boolean pressMenu();
+    method @Deprecated public boolean pressRecentApps() throws android.os.RemoteException;
+    method @Deprecated public boolean pressSearch();
+    method @Deprecated public void registerWatcher(String, com.android.uiautomator.core.UiWatcher);
+    method @Deprecated public void removeWatcher(String);
+    method @Deprecated public void resetWatcherTriggers();
+    method @Deprecated public void runWatchers();
+    method @Deprecated public void setCompressedLayoutHeirarchy(boolean);
+    method @Deprecated public void setOrientationLeft() throws android.os.RemoteException;
+    method @Deprecated public void setOrientationNatural() throws android.os.RemoteException;
+    method @Deprecated public void setOrientationRight() throws android.os.RemoteException;
+    method @Deprecated public void sleep() throws android.os.RemoteException;
+    method @Deprecated public boolean swipe(int, int, int, int, int);
+    method @Deprecated public boolean swipe(android.graphics.Point[], int);
+    method @Deprecated public boolean takeScreenshot(java.io.File);
+    method @Deprecated public boolean takeScreenshot(java.io.File, float, int);
+    method @Deprecated public void unfreezeRotation() throws android.os.RemoteException;
+    method @Deprecated public void waitForIdle();
+    method @Deprecated public void waitForIdle(long);
+    method @Deprecated public boolean waitForWindowUpdate(String, long);
+    method @Deprecated public void wakeUp() throws android.os.RemoteException;
   }
 
-  public deprecated class UiObject {
-    ctor public UiObject(com.android.uiautomator.core.UiSelector);
-    method public void clearTextField() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean click() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean clickAndWaitForNewWindow() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean clickAndWaitForNewWindow(long) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean clickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean clickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean dragTo(com.android.uiautomator.core.UiObject, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean dragTo(int, int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean exists();
-    method protected android.view.accessibility.AccessibilityNodeInfo findAccessibilityNodeInfo(long);
-    method public android.graphics.Rect getBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public com.android.uiautomator.core.UiObject getChild(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public int getChildCount() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public java.lang.String getClassName() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public java.lang.String getContentDescription() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public com.android.uiautomator.core.UiObject getFromParent(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public java.lang.String getPackageName() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public final com.android.uiautomator.core.UiSelector getSelector();
-    method public java.lang.String getText() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public android.graphics.Rect getVisibleBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean isCheckable() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean isChecked() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean isClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean isEnabled() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean isFocusable() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean isFocused() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean isLongClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean isScrollable() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean isSelected() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean longClick() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean longClickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean longClickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean performMultiPointerGesture(android.view.MotionEvent.PointerCoords...);
-    method public boolean performTwoPointerGesture(android.graphics.Point, android.graphics.Point, android.graphics.Point, android.graphics.Point, int);
-    method public boolean pinchIn(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean pinchOut(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean setText(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean swipeDown(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean swipeLeft(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean swipeRight(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean swipeUp(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean waitForExists(long);
-    method public boolean waitUntilGone(long);
-    field protected static final int FINGER_TOUCH_HALF_WIDTH = 20; // 0x14
-    field protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
-    field protected static final deprecated long WAIT_FOR_EVENT_TMEOUT = 3000L; // 0xbb8L
-    field protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
-    field protected static final deprecated long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
-    field protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
+  @Deprecated public class UiObject {
+    ctor @Deprecated public UiObject(com.android.uiautomator.core.UiSelector);
+    method @Deprecated public void clearTextField() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean click() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean clickAndWaitForNewWindow() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean clickAndWaitForNewWindow(long) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean clickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean clickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean dragTo(com.android.uiautomator.core.UiObject, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean dragTo(int, int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean exists();
+    method @Deprecated protected android.view.accessibility.AccessibilityNodeInfo findAccessibilityNodeInfo(long);
+    method @Deprecated public android.graphics.Rect getBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public com.android.uiautomator.core.UiObject getChild(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public int getChildCount() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public String getClassName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public String getContentDescription() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public com.android.uiautomator.core.UiObject getFromParent(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public String getPackageName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public final com.android.uiautomator.core.UiSelector getSelector();
+    method @Deprecated public String getText() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public android.graphics.Rect getVisibleBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean isCheckable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean isChecked() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean isClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean isEnabled() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean isFocusable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean isFocused() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean isLongClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean isScrollable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean isSelected() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean longClick() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean longClickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean longClickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean performMultiPointerGesture(android.view.MotionEvent.PointerCoords[]...);
+    method @Deprecated public boolean performTwoPointerGesture(android.graphics.Point, android.graphics.Point, android.graphics.Point, android.graphics.Point, int);
+    method @Deprecated public boolean pinchIn(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean pinchOut(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean setText(String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean swipeDown(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean swipeLeft(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean swipeRight(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean swipeUp(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean waitForExists(long);
+    method @Deprecated public boolean waitUntilGone(long);
+    field @Deprecated protected static final int FINGER_TOUCH_HALF_WIDTH = 20; // 0x14
+    field @Deprecated protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
+    field @Deprecated protected static final long WAIT_FOR_EVENT_TMEOUT = 3000L; // 0xbb8L
+    field @Deprecated protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
+    field @Deprecated protected static final long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
+    field @Deprecated protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
   }
 
-  public deprecated class UiObjectNotFoundException extends java.lang.Exception {
-    ctor public UiObjectNotFoundException(java.lang.String);
-    ctor public UiObjectNotFoundException(java.lang.String, java.lang.Throwable);
-    ctor public UiObjectNotFoundException(java.lang.Throwable);
+  @Deprecated public class UiObjectNotFoundException extends java.lang.Exception {
+    ctor @Deprecated public UiObjectNotFoundException(String);
+    ctor @Deprecated public UiObjectNotFoundException(String, Throwable);
+    ctor @Deprecated public UiObjectNotFoundException(Throwable);
   }
 
-  public deprecated class UiScrollable extends com.android.uiautomator.core.UiCollection {
-    ctor public UiScrollable(com.android.uiautomator.core.UiSelector);
-    method protected boolean exists(com.android.uiautomator.core.UiSelector);
-    method public boolean flingBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean flingForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean flingToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean flingToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public int getMaxSearchSwipes();
-    method public double getSwipeDeadZonePercentage();
-    method public boolean scrollBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollBackward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollDescriptionIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollForward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollIntoView(com.android.uiautomator.core.UiObject) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollIntoView(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollTextIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollToBeginning(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollToEnd(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public boolean scrollToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
-    method public com.android.uiautomator.core.UiScrollable setAsHorizontalList();
-    method public com.android.uiautomator.core.UiScrollable setAsVerticalList();
-    method public com.android.uiautomator.core.UiScrollable setMaxSearchSwipes(int);
-    method public com.android.uiautomator.core.UiScrollable setSwipeDeadZonePercentage(double);
+  @Deprecated public class UiScrollable extends com.android.uiautomator.core.UiCollection {
+    ctor @Deprecated public UiScrollable(com.android.uiautomator.core.UiSelector);
+    method @Deprecated protected boolean exists(com.android.uiautomator.core.UiSelector);
+    method @Deprecated public boolean flingBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean flingForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean flingToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean flingToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public int getMaxSearchSwipes();
+    method @Deprecated public double getSwipeDeadZonePercentage();
+    method @Deprecated public boolean scrollBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollBackward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollDescriptionIntoView(String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollForward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollIntoView(com.android.uiautomator.core.UiObject) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollIntoView(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollTextIntoView(String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollToBeginning(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollToEnd(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public boolean scrollToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method @Deprecated public com.android.uiautomator.core.UiScrollable setAsHorizontalList();
+    method @Deprecated public com.android.uiautomator.core.UiScrollable setAsVerticalList();
+    method @Deprecated public com.android.uiautomator.core.UiScrollable setMaxSearchSwipes(int);
+    method @Deprecated public com.android.uiautomator.core.UiScrollable setSwipeDeadZonePercentage(double);
   }
 
-  public deprecated class UiSelector {
-    ctor public UiSelector();
-    method public com.android.uiautomator.core.UiSelector checkable(boolean);
-    method public com.android.uiautomator.core.UiSelector checked(boolean);
-    method public com.android.uiautomator.core.UiSelector childSelector(com.android.uiautomator.core.UiSelector);
-    method public com.android.uiautomator.core.UiSelector className(java.lang.String);
-    method public <T> com.android.uiautomator.core.UiSelector className(java.lang.Class<T>);
-    method public com.android.uiautomator.core.UiSelector classNameMatches(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector clickable(boolean);
-    method protected com.android.uiautomator.core.UiSelector cloneSelector();
-    method public com.android.uiautomator.core.UiSelector description(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector descriptionContains(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector descriptionMatches(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector descriptionStartsWith(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector enabled(boolean);
-    method public com.android.uiautomator.core.UiSelector focusable(boolean);
-    method public com.android.uiautomator.core.UiSelector focused(boolean);
-    method public com.android.uiautomator.core.UiSelector fromParent(com.android.uiautomator.core.UiSelector);
-    method public com.android.uiautomator.core.UiSelector index(int);
-    method public com.android.uiautomator.core.UiSelector instance(int);
-    method public com.android.uiautomator.core.UiSelector longClickable(boolean);
-    method public com.android.uiautomator.core.UiSelector packageName(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector packageNameMatches(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector resourceId(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector resourceIdMatches(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector scrollable(boolean);
-    method public com.android.uiautomator.core.UiSelector selected(boolean);
-    method public com.android.uiautomator.core.UiSelector text(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector textContains(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector textMatches(java.lang.String);
-    method public com.android.uiautomator.core.UiSelector textStartsWith(java.lang.String);
+  @Deprecated public class UiSelector {
+    ctor @Deprecated public UiSelector();
+    method @Deprecated public com.android.uiautomator.core.UiSelector checkable(boolean);
+    method @Deprecated public com.android.uiautomator.core.UiSelector checked(boolean);
+    method @Deprecated public com.android.uiautomator.core.UiSelector childSelector(com.android.uiautomator.core.UiSelector);
+    method @Deprecated public com.android.uiautomator.core.UiSelector className(String);
+    method @Deprecated public <T> com.android.uiautomator.core.UiSelector className(Class<T>);
+    method @Deprecated public com.android.uiautomator.core.UiSelector classNameMatches(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector clickable(boolean);
+    method @Deprecated protected com.android.uiautomator.core.UiSelector cloneSelector();
+    method @Deprecated public com.android.uiautomator.core.UiSelector description(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector descriptionContains(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector descriptionMatches(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector descriptionStartsWith(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector enabled(boolean);
+    method @Deprecated public com.android.uiautomator.core.UiSelector focusable(boolean);
+    method @Deprecated public com.android.uiautomator.core.UiSelector focused(boolean);
+    method @Deprecated public com.android.uiautomator.core.UiSelector fromParent(com.android.uiautomator.core.UiSelector);
+    method @Deprecated public com.android.uiautomator.core.UiSelector index(int);
+    method @Deprecated public com.android.uiautomator.core.UiSelector instance(int);
+    method @Deprecated public com.android.uiautomator.core.UiSelector longClickable(boolean);
+    method @Deprecated public com.android.uiautomator.core.UiSelector packageName(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector packageNameMatches(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector resourceId(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector resourceIdMatches(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector scrollable(boolean);
+    method @Deprecated public com.android.uiautomator.core.UiSelector selected(boolean);
+    method @Deprecated public com.android.uiautomator.core.UiSelector text(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector textContains(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector textMatches(String);
+    method @Deprecated public com.android.uiautomator.core.UiSelector textStartsWith(String);
   }
 
-  public abstract deprecated interface UiWatcher {
-    method public abstract boolean checkForCondition();
+  @Deprecated public interface UiWatcher {
+    method @Deprecated public boolean checkForCondition();
   }
 
 }
 
 package com.android.uiautomator.testrunner {
 
-  public abstract deprecated interface IAutomationSupport {
-    method public abstract void sendStatus(int, android.os.Bundle);
+  @Deprecated public interface IAutomationSupport {
+    method @Deprecated public void sendStatus(int, android.os.Bundle);
   }
 
-  public deprecated class UiAutomatorTestCase extends junit.framework.TestCase {
-    ctor public UiAutomatorTestCase();
-    method public com.android.uiautomator.testrunner.IAutomationSupport getAutomationSupport();
-    method public android.os.Bundle getParams();
-    method public com.android.uiautomator.core.UiDevice getUiDevice();
-    method public void sleep(long);
+  @Deprecated public class UiAutomatorTestCase extends junit.framework.TestCase {
+    ctor @Deprecated public UiAutomatorTestCase();
+    method @Deprecated public com.android.uiautomator.testrunner.IAutomationSupport getAutomationSupport();
+    method @Deprecated public android.os.Bundle getParams();
+    method @Deprecated public com.android.uiautomator.core.UiDevice getUiDevice();
+    method @Deprecated public void sleep(long);
   }
 
 }
diff --git a/cmds/uiautomator/api/removed.txt b/cmds/uiautomator/api/removed.txt
index e69de29..d802177 100644
--- a/cmds/uiautomator/api/removed.txt
+++ b/cmds/uiautomator/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/cmds/uiautomator/library/Android.bp b/cmds/uiautomator/library/Android.bp
index c33d31f..04b00cb 100644
--- a/cmds/uiautomator/library/Android.bp
+++ b/cmds/uiautomator/library/Android.bp
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-droiddoc {
-    name: "uiautomator-stubs-docs",
+droidstubs {
+    name: "uiautomator-stubs",
     srcs: [
         "core-src/**/*.java",
         "testrunner-src/**/*.java",
@@ -24,10 +24,10 @@
         "android.test.base",
         "unsupportedappusage",
     ],
-    custom_template: "droiddoc-templates-sdk",
     installable: false,
-    args: "-stubpackages com.android.uiautomator.core:" +
-          "com.android.uiautomator.testrunner",
+    flags: [
+        "-stubpackages com.android.uiautomator.core:com.android.uiautomator.testrunner",
+    ],
 
     check_api: {
         current: {
@@ -41,10 +41,26 @@
     },
 }
 
+droiddoc {
+    name: "uiautomator-stubs-docs",
+    srcs: [
+        ":uiautomator-stubs",
+    ],
+    libs: [
+        "android.test.runner",
+        "junit",
+        "android.test.base",
+        "unsupportedappusage",
+    ],
+    installable: false,
+    custom_template: "droiddoc-templates-sdk",
+    create_stubs: false,
+}
+
 java_library_static {
     name: "android_uiautomator",
     srcs: [
-        ":uiautomator-stubs-docs",
+        ":uiautomator-stubs",
     ],
     libs: [
         "android.test.runner",
@@ -64,7 +80,7 @@
     ],
     static_libs: [
         "junit",
-    ]
+    ],
 }
 
 java_library_static {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index a2cf7d9..8d68cdb 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1450,7 +1450,7 @@
      * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
      * if service discovery is not to be performed.
      *
-     * @return False if the sanity check fails, True if the process of initiating an ACL connection
+     * @return False if the check fails, True if the process of initiating an ACL connection
      * to the remote device was started.
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
@@ -1484,7 +1484,7 @@
      * The object type will match one of the SdpXxxRecord types, depending on the UUID searched
      * for.
      *
-     * @return False if the sanity check fails, True if the process
+     * @return False if the check fails, True if the process
      *               of initiating an ACL connection to the remote device
      *               was started.
      */
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index a50831f..d1a7eb8 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -594,7 +594,7 @@
 
     /**
      * In addition to {@link #SYNC_EXEMPTION_PROMOTE_BUCKET}, we put the sync adapter app in the
-     * temp whitelist for 10 minutes, so that even RARE apps can run syncs right away.
+     * temp allowlist for 10 minutes, so that even RARE apps can run syncs right away.
      * @hide
      */
     public static final int SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP = 2;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 62669e0..9b46afa 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -921,7 +921,7 @@
      * Automatically detects if the package is a monolithic style (single APK
      * file) or cluster style (directory of APKs).
      * <p>
-     * This performs sanity checking on cluster style packages, such as
+     * This performs checking on cluster style packages, such as
      * requiring identical package name and version codes, a single base APK,
      * and unique split names.
      *
@@ -1038,7 +1038,7 @@
      * package is a monolithic style (single APK file) or cluster style
      * (directory of APKs).
      * <p>
-     * This performs sanity checking on cluster style packages, such as
+     * This performs checking on cluster style packages, such as
      * requiring identical package name and version codes, a single base APK,
      * and unique split names.
      * <p>
@@ -1255,7 +1255,7 @@
 
     /**
      * Parse all APKs contained in the given directory, treating them as a
-     * single package. This also performs sanity checking, such as requiring
+     * single package. This also performs checking, such as requiring
      * identical package name and version codes, a single base APK, and unique
      * split names.
      * <p>
diff --git a/core/java/android/content/pm/dex/DexMetadataHelper.java b/core/java/android/content/pm/dex/DexMetadataHelper.java
index 5d10b88..42b8753 100644
--- a/core/java/android/content/pm/dex/DexMetadataHelper.java
+++ b/core/java/android/content/pm/dex/DexMetadataHelper.java
@@ -170,7 +170,7 @@
 
     /**
      * Validate that the given file is a dex metadata archive.
-     * This is just a sanity validation that the file is a zip archive.
+     * This is just a validation that the file is a zip archive.
      *
      * @throws PackageParserException if the file is not a .dm file.
      */
@@ -196,7 +196,7 @@
      * (for any foo.dm there should be either a 'foo' of a 'foo.apk' file).
      * If that's not the case it throws {@code IllegalStateException}.
      *
-     * This is used to perform a basic sanity check during adb install commands.
+     * This is used to perform a basic check during adb install commands.
      * (The installer does not support stand alone .dm files)
      */
     public static void validateDexPaths(String[] paths) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index cec6382..5e1a92b 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1772,7 +1772,7 @@
      */
     public boolean isOtherSeqNewer(Configuration other) {
         if (other == null) {
-            // Sanity check.
+            // Validation check.
             return false;
         }
         if (other.seq == 0) {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 9c994eb..8b9b0c1 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -608,7 +608,7 @@
     public static final int TYPE_BLUETOOTH   = 7;
 
     /**
-     * Dummy data connection.  This should not be used on shipping devices.
+     * Fake data connection.  This should not be used on shipping devices.
      * @deprecated This is not used any more.
      */
     @Deprecated
@@ -1084,9 +1084,9 @@
      *                   to remove an existing always-on VPN configuration.
      * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
      *        {@code false} otherwise.
-     * @param lockdownWhitelist The list of packages that are allowed to access network directly
+     * @param lockdownAllowlist The list of packages that are allowed to access network directly
      *         when VPN is in lockdown mode but is not running. Non-existent packages are ignored so
-     *         this method must be called when a package that should be whitelisted is installed or
+     *         this method must be called when a package that should be allowed is installed or
      *         uninstalled.
      * @return {@code true} if the package is set as always-on VPN controller;
      *         {@code false} otherwise.
@@ -1094,10 +1094,10 @@
      */
     @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
     public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
-            boolean lockdownEnabled, @Nullable List<String> lockdownWhitelist) {
+            boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
         try {
             return mService.setAlwaysOnVpnPackage(
-                    userId, vpnPackage, lockdownEnabled, lockdownWhitelist);
+                    userId, vpnPackage, lockdownEnabled, lockdownAllowlist);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index e449615..713b688 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -28,7 +28,7 @@
  * @hide
  */
 public class NetworkState implements Parcelable {
-    private static final boolean SANITY_CHECK_ROAMING = false;
+    private static final boolean VALIDATE_ROAMING_STATE = false;
 
     public static final NetworkState EMPTY = new NetworkState(null, null, null, null, null, null);
 
@@ -52,7 +52,7 @@
 
         // This object is an atomic view of a network, so the various components
         // should always agree on roaming state.
-        if (SANITY_CHECK_ROAMING && networkInfo != null && networkCapabilities != null) {
+        if (VALIDATE_ROAMING_STATE && networkInfo != null && networkCapabilities != null) {
             if (networkInfo.isRoaming() == networkCapabilities
                     .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
                 Slog.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index c82c288..897b67c 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -26,6 +26,7 @@
 import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
 import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
 import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
+import static android.net.NetworkUtils.multiplySafeByRational;
 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
 
 import static com.android.internal.util.ArrayUtils.total;
@@ -364,11 +365,12 @@
             if (overlap <= 0) continue;
 
             // integer math each time is faster than floating point
-            final long fracRxBytes = rxBytes * overlap / duration;
-            final long fracRxPackets = rxPackets * overlap / duration;
-            final long fracTxBytes = txBytes * overlap / duration;
-            final long fracTxPackets = txPackets * overlap / duration;
-            final long fracOperations = operations * overlap / duration;
+            final long fracRxBytes = multiplySafeByRational(rxBytes, overlap, duration);
+            final long fracRxPackets = multiplySafeByRational(rxPackets, overlap, duration);
+            final long fracTxBytes = multiplySafeByRational(txBytes, overlap, duration);
+            final long fracTxPackets = multiplySafeByRational(txPackets, overlap, duration);
+            final long fracOperations = multiplySafeByRational(operations, overlap, duration);
+
 
             addLong(activeTime, i, overlap);
             addLong(this.rxBytes, i, fracRxBytes); rxBytes -= fracRxBytes;
@@ -568,12 +570,24 @@
             if (overlap <= 0) continue;
 
             // integer math each time is faster than floating point
-            if (activeTime != null) entry.activeTime += activeTime[i] * overlap / bucketSpan;
-            if (rxBytes != null) entry.rxBytes += rxBytes[i] * overlap / bucketSpan;
-            if (rxPackets != null) entry.rxPackets += rxPackets[i] * overlap / bucketSpan;
-            if (txBytes != null) entry.txBytes += txBytes[i] * overlap / bucketSpan;
-            if (txPackets != null) entry.txPackets += txPackets[i] * overlap / bucketSpan;
-            if (operations != null) entry.operations += operations[i] * overlap / bucketSpan;
+            if (activeTime != null) {
+                entry.activeTime += multiplySafeByRational(activeTime[i], overlap, bucketSpan);
+            }
+            if (rxBytes != null) {
+                entry.rxBytes += multiplySafeByRational(rxBytes[i], overlap, bucketSpan);
+            }
+            if (rxPackets != null) {
+                entry.rxPackets += multiplySafeByRational(rxPackets[i], overlap, bucketSpan);
+            }
+            if (txBytes != null) {
+                entry.txBytes += multiplySafeByRational(txBytes[i], overlap, bucketSpan);
+            }
+            if (txPackets != null) {
+                entry.txPackets += multiplySafeByRational(txPackets[i], overlap, bucketSpan);
+            }
+            if (operations != null) {
+                entry.operations += multiplySafeByRational(operations[i], overlap, bucketSpan);
+            }
         }
         return entry;
     }
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 0b92b95..1e004e4 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -476,4 +476,35 @@
 
         return true;
     }
+
+    /**
+     * Safely multiple a value by a rational.
+     * <p>
+     * Internally it uses integer-based math whenever possible, but switches
+     * over to double-based math if values would overflow.
+     * @hide
+     */
+    public static long multiplySafeByRational(long value, long num, long den) {
+        if (den == 0) {
+            throw new ArithmeticException("Invalid Denominator");
+        }
+        long x = value;
+        long y = num;
+
+        // Logic shamelessly borrowed from Math.multiplyExact()
+        long r = x * y;
+        long ax = Math.abs(x);
+        long ay = Math.abs(y);
+        if (((ax | ay) >>> 31 != 0)) {
+            // Some bits greater than 2^31 that might cause overflow
+            // Check the result using the divide operator
+            // and check for the special case of Long.MIN_VALUE * -1
+            if (((y != 0) && (r / y != x)) ||
+                    (x == Long.MIN_VALUE && y == -1)) {
+                // Use double math to avoid overflowing
+                return (long) (((double) num / den) * value);
+            }
+        }
+        return r / den;
+    }
 }
diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java
index 8c6faf6..f6852e6 100644
--- a/core/java/android/net/SntpClient.java
+++ b/core/java/android/net/SntpClient.java
@@ -25,6 +25,7 @@
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.Arrays;
 
 /**
@@ -86,21 +87,26 @@
      * Sends an SNTP request to the given host and processes the response.
      *
      * @param host host name of the server.
-     * @param timeout network timeout in milliseconds.
+     * @param timeout network timeout in milliseconds. the timeout doesn't include the DNS lookup
+     *                time, and it applies to each individual query to the resolved addresses of
+     *                the NTP server.
      * @param network network over which to send the request.
      * @return true if the transaction was successful.
      */
     public boolean requestTime(String host, int timeout, Network network) {
         final Network networkForResolv = network.getPrivateDnsBypassingCopy();
-        InetAddress address = null;
         try {
-            address = networkForResolv.getByName(host);
-        } catch (Exception e) {
+            final InetAddress[] addresses = networkForResolv.getAllByName(host);
+            for (int i = 0; i < addresses.length; i++) {
+                if (requestTime(addresses[i], NTP_PORT, timeout, networkForResolv)) return true;
+            }
+        } catch (UnknownHostException e) {
+            Log.w(TAG, "Unknown host: " + host);
             EventLogTags.writeNtpFailure(host, e.toString());
-            if (DBG) Log.d(TAG, "request time failed: " + e);
-            return false;
         }
-        return requestTime(address, NTP_PORT, timeout, networkForResolv);
+
+        if (DBG) Log.d(TAG, "request time failed");
+        return false;
     }
 
     public boolean requestTime(InetAddress address, int port, int timeout, Network network) {
@@ -139,10 +145,11 @@
             final long originateTime = readTimeStamp(buffer, ORIGINATE_TIME_OFFSET);
             final long receiveTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
             final long transmitTime = readTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
+            final long referenceTime = readTimeStamp(buffer, REFERENCE_TIME_OFFSET);
 
-            /* do sanity check according to RFC */
+            /* Do validation according to RFC */
             // TODO: validate originateTime == requestTime.
-            checkValidServerReply(leap, mode, stratum, transmitTime);
+            checkValidServerReply(leap, mode, stratum, transmitTime, referenceTime);
 
             long roundTripTime = responseTicks - requestTicks - (transmitTime - receiveTime);
             // receiveTime = originateTime + transit + skew
@@ -218,7 +225,7 @@
     }
 
     private static void checkValidServerReply(
-            byte leap, byte mode, int stratum, long transmitTime)
+            byte leap, byte mode, int stratum, long transmitTime, long referenceTime)
             throws InvalidServerReplyException {
         if (leap == NTP_LEAP_NOSYNC) {
             throw new InvalidServerReplyException("unsynchronized server");
@@ -232,6 +239,9 @@
         if (transmitTime == 0) {
             throw new InvalidServerReplyException("zero transmitTime");
         }
+        if (referenceTime == 0) {
+            throw new InvalidServerReplyException("zero reference timestamp");
+        }
     }
 
     /**
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 9c2c5b8..8e90a119 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -119,7 +119,7 @@
  * <p> The Android system starts a VPN in the background by calling
  * {@link android.content.Context#startService startService()}. In Android 8.0
  * (API level 26) and higher, the system places VPN apps on the temporary
- * whitelist for a short period so the app can start in the background. The VPN
+ * allowlist for a short period so the app can start in the background. The VPN
  * app must promote itself to the foreground after it's launched or the system
  * will shut down the app.
  *
diff --git a/core/java/android/os/Parcelable.java b/core/java/android/os/Parcelable.java
index bedbba0..3d3759e 100644
--- a/core/java/android/os/Parcelable.java
+++ b/core/java/android/os/Parcelable.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.annotation.IntDef;
+import android.annotation.SystemApi;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -119,6 +120,7 @@
      * @see ParcelableHolder
      * @hide
      */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int PARCELABLE_STABILITY_LOCAL = 0x0000;
     /**
      * Something that is meant to be used between system and vendor.
@@ -126,6 +128,7 @@
      * @see ParcelableHolder
      * @hide
      */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int PARCELABLE_STABILITY_VINTF = 0x0001;
 
     /**
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 57068fa..00872fb 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -216,7 +216,7 @@
          * in {@link Builder#build()}, recursively if needed.
          */
         public Builder setParent(Builder parent) {
-            // Sanity check to avoid adding loops.
+            // Quick check to avoid adding loops.
             Builder current = parent;
             while (current != null) {
                 if (current == this) {
diff --git a/core/java/android/text/format/DateIntervalFormat.java b/core/java/android/text/format/DateIntervalFormat.java
index de9ec7a..e8236fd 100644
--- a/core/java/android/text/format/DateIntervalFormat.java
+++ b/core/java/android/text/format/DateIntervalFormat.java
@@ -62,7 +62,7 @@
 
     /**
      * Format a date range. This is our slightly more sensible internal API.
-     * A truly sane replacement would take a skeleton instead of int flags.
+     * A truly reasonable replacement would take a skeleton instead of int flags.
      */
     @VisibleForTesting(visibility = PACKAGE)
     public static String formatDateRange(ULocale icuLocale, android.icu.util.TimeZone icuTimeZone,
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 271d5be..94bf4b1 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1497,7 +1497,7 @@
      *
      * @param hosts the list of hosts
      * @param callback will be called with {@code true} if hosts are successfully added to the
-     * whitelist. It will be called with {@code false} if any hosts are malformed. The callback
+     * allowlist. It will be called with {@code false} if any hosts are malformed. The callback
      * will be run on the UI thread
      */
     public static void setSafeBrowsingWhitelist(@NonNull List<String> hosts,
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 150fa88..7b6e1a3 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -173,8 +173,9 @@
      * when accessing private data or the view system.
      *
      * <p class="note"><b>Note:</b> When Safe Browsing is enabled, these URLs still undergo Safe
-     * Browsing checks. If this is undesired, whitelist the URL with {@link
-     * WebView#setSafeBrowsingWhitelist} or ignore the warning with {@link #onSafeBrowsingHit}.
+     * Browsing checks. If this is undesired, you can use {@link WebView#setSafeBrowsingWhitelist}
+     * to skip Safe Browsing checks for that host or dismiss the warning in {@link
+     * #onSafeBrowsingHit} by calling {@link SafeBrowsingResponse#proceed}.
      *
      * @param view The {@link android.webkit.WebView} that is requesting the
      *             resource.
@@ -211,8 +212,9 @@
      * when accessing private data or the view system.
      *
      * <p class="note"><b>Note:</b> When Safe Browsing is enabled, these URLs still undergo Safe
-     * Browsing checks. If this is undesired, whitelist the URL with {@link
-     * WebView#setSafeBrowsingWhitelist} or ignore the warning with {@link #onSafeBrowsingHit}.
+     * Browsing checks. If this is undesired, you can use {@link WebView#setSafeBrowsingWhitelist}
+     * to skip Safe Browsing checks for that host or dismiss the warning in {@link
+     * #onSafeBrowsingHit} by calling {@link SafeBrowsingResponse#proceed}.
      *
      * @param view The {@link android.webkit.WebView} that is requesting the
      *             resource.
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 3343593f..0c43578 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.app;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.ListFragment;
@@ -28,6 +30,7 @@
 import android.os.LocaleList;
 import android.os.RemoteException;
 import android.provider.Settings;
+import android.sysprop.LocalizationProperties;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -43,6 +46,9 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 
 public class LocalePicker extends ListFragment {
     private static final String TAG = "LocalePicker";
@@ -92,7 +98,38 @@
     }
 
     public static String[] getSupportedLocales(Context context) {
-        return context.getResources().getStringArray(R.array.supported_locales);
+        String[] allLocales = context.getResources().getStringArray(R.array.supported_locales);
+
+        Predicate<String> localeFilter = getLocaleFilter();
+        if (localeFilter == null) {
+            return allLocales;
+        }
+
+        List<String> result = new ArrayList<>(allLocales.length);
+        for (String locale : allLocales) {
+            if (localeFilter.test(locale)) {
+                result.add(locale);
+            }
+        }
+
+        int localeCount = result.size();
+        return (localeCount == allLocales.length) ? allLocales
+                : result.toArray(new String[localeCount]);
+    }
+
+    @Nullable
+    private static Predicate<String> getLocaleFilter() {
+        try {
+            return LocalizationProperties.locale_filter()
+                    .map(filter -> Pattern.compile(filter).asPredicate())
+                    .orElse(null);
+        } catch (SecurityException e) {
+            Log.e(TAG, "Failed to read locale filter.", e);
+        } catch (PatternSyntaxException e) {
+            Log.e(TAG, "Bad locale filter format (\"" + e.getPattern() + "\"), skipping.");
+        }
+
+        return null;
     }
 
     public static List<LocaleInfo> getAllAssetLocales(Context context, boolean isInDeveloperMode) {
@@ -265,6 +302,11 @@
      */
     @UnsupportedAppUsage
     public static void updateLocales(LocaleList locales) {
+        if (locales != null) {
+            locales = removeExcludedLocales(locales);
+        }
+        // Note: the empty list case is covered by Configuration.setLocales().
+
         try {
             final IActivityManager am = ActivityManager.getService();
             final Configuration config = am.getConfiguration();
@@ -280,6 +322,26 @@
         }
     }
 
+    @NonNull
+    private static LocaleList removeExcludedLocales(@NonNull LocaleList locales) {
+        Predicate<String> localeFilter = getLocaleFilter();
+        if (localeFilter == null) {
+            return locales;
+        }
+
+        int localeCount = locales.size();
+        ArrayList<Locale> filteredLocales = new ArrayList<>(localeCount);
+        for (int i = 0; i < localeCount; ++i) {
+            Locale locale = locales.get(i);
+            if (localeFilter.test(locale.toString())) {
+                filteredLocales.add(locale);
+            }
+        }
+
+        return (localeCount == filteredLocales.size()) ? locales
+                : new LocaleList(filteredLocales.toArray(new Locale[0]));
+    }
+
     /**
      * Get the locale list.
      *
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3d73ade..83e29ad 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2954,6 +2954,9 @@
              eutran : eutranSupportedRelease
              nfc : contactlessSupportedRelease
              crl : rspCrlSupportedVersion
+             nrepc : nrEpcSupportedRelease
+             nr5gc : nr5gcSupportedRelease
+             eutran5gc : eutran5gcSupportedRelease
     -->
     <string-array translatable="false" name="config_telephonyEuiccDeviceCapabilities">
         <!-- Example:
@@ -2965,6 +2968,9 @@
         <item>"eutran,11"</item>
         <item>"nfc,1"</item>
         <item>"crl,1"</item>
+        <item>"nrepc,15"</item>
+        <item>"nr5gc,15"</item>
+        <item>"eutran5gc,15"</item>
         -->
     </string-array>
 
diff --git a/core/sysprop/Android.bp b/core/sysprop/Android.bp
new file mode 100644
index 0000000..7f20a0b
--- /dev/null
+++ b/core/sysprop/Android.bp
@@ -0,0 +1,21 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+sysprop_library {
+    name: "com.android.sysprop.localization",
+    srcs: ["LocalizationProperties.sysprop"],
+    property_owner: "Platform",
+    api_packages: ["android.sysprop"],
+    vendor_available: false,
+}
diff --git a/core/sysprop/LocalizationProperties.sysprop b/core/sysprop/LocalizationProperties.sysprop
new file mode 100644
index 0000000..65f544f
--- /dev/null
+++ b/core/sysprop/LocalizationProperties.sysprop
@@ -0,0 +1,24 @@
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module: "android.sysprop.LocalizationProperties"
+owner: Platform
+
+prop {
+    api_name: "locale_filter"
+    type: String
+    prop_name: "ro.localization.locale_filter"
+    scope: Internal
+    access: Readonly
+}
diff --git a/core/sysprop/api/com.android.sysprop.localization-current.txt b/core/sysprop/api/com.android.sysprop.localization-current.txt
new file mode 100644
index 0000000..fe4f457
--- /dev/null
+++ b/core/sysprop/api/com.android.sysprop.localization-current.txt
@@ -0,0 +1,9 @@
+props {
+  module: "android.sysprop.LocalizationProperties"
+  prop {
+    api_name: "locale_filter"
+    type: String
+    scope: Internal
+    prop_name: "ro.localization.locale_filter"
+  }
+}
diff --git a/core/sysprop/api/com.android.sysprop.localization-latest.txt b/core/sysprop/api/com.android.sysprop.localization-latest.txt
new file mode 100644
index 0000000..fe4f457
--- /dev/null
+++ b/core/sysprop/api/com.android.sysprop.localization-latest.txt
@@ -0,0 +1,9 @@
+props {
+  module: "android.sysprop.LocalizationProperties"
+  prop {
+    api_name: "locale_filter"
+    type: String
+    scope: Internal
+    prop_name: "ro.localization.locale_filter"
+  }
+}
diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java
index af3660a..ae6e79a 100644
--- a/core/tests/coretests/src/android/os/VintfObjectTest.java
+++ b/core/tests/coretests/src/android/os/VintfObjectTest.java
@@ -20,7 +20,7 @@
 
 public class VintfObjectTest extends TestCase {
     /**
-     * Sanity check for {@link VintfObject#report VintfObject.report()}.
+     * Quick check for {@link VintfObject#report VintfObject.report()}.
      */
     public void testReport() {
         String[] xmls = VintfObject.report();
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index c55eeeb..05cf625 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -43412,6 +43412,7 @@
 package android.telecom {
 
   public final class Call {
+    method public void addConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
     method public void answer(int);
     method public void conference(android.telecom.Call);
     method public void deflect(android.net.Uri);
@@ -43520,6 +43521,7 @@
     method public static boolean hasProperty(int, int);
     method public boolean hasProperty(int);
     method public static String propertiesToString(int);
+    field public static final int CAPABILITY_ADD_PARTICIPANT = 33554432; // 0x2000000
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_CAN_PULL_CALL = 8388608; // 0x800000
@@ -43549,6 +43551,7 @@
     field public static final int PROPERTY_GENERIC_CONFERENCE = 2; // 0x2
     field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 128; // 0x80
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
+    field public static final int PROPERTY_IS_ADHOC_CONFERENCE = 8192; // 0x2000
     field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
     field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 2048; // 0x800
     field public static final int PROPERTY_RTT = 1024; // 0x400
@@ -43626,6 +43629,7 @@
   public abstract class Conference extends android.telecom.Conferenceable {
     ctor public Conference(android.telecom.PhoneAccountHandle);
     method public final boolean addConnection(android.telecom.Connection);
+    method @NonNull public static android.telecom.Conference createFailedConference(@NonNull android.telecom.DisconnectCause, @NonNull android.telecom.PhoneAccountHandle);
     method public final void destroy();
     method public final android.telecom.CallAudioState getCallAudioState();
     method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
@@ -43641,6 +43645,9 @@
     method public final android.telecom.StatusHints getStatusHints();
     method public android.telecom.Connection.VideoProvider getVideoProvider();
     method public int getVideoState();
+    method public final boolean isRingbackRequested();
+    method public void onAddConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
+    method public void onAnswer(int);
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onConnectionAdded(android.telecom.Connection);
     method public void onDisconnect();
@@ -43649,6 +43656,7 @@
     method public void onMerge(android.telecom.Connection);
     method public void onMerge();
     method public void onPlayDtmfTone(char);
+    method public void onReject();
     method public void onSeparate(android.telecom.Connection);
     method public void onStopDtmfTone();
     method public void onSwap();
@@ -43669,6 +43677,8 @@
     method public final void setDisconnected(android.telecom.DisconnectCause);
     method public final void setExtras(@Nullable android.os.Bundle);
     method public final void setOnHold();
+    method public final void setRingbackRequested(boolean);
+    method public final void setRinging();
     method public final void setStatusHints(android.telecom.StatusHints);
     method public final void setVideoProvider(android.telecom.Connection, android.telecom.Connection.VideoProvider);
     method public final void setVideoState(android.telecom.Connection, int);
@@ -43705,6 +43715,7 @@
     method public final boolean isRingbackRequested();
     method public final void notifyConferenceMergeFailed();
     method public void onAbort();
+    method public void onAddConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
     method public void onAnswer(int);
     method public void onAnswer();
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
@@ -43784,6 +43795,7 @@
     field public static final int AUDIO_CODEC_GSM_HR = 10; // 0xa
     field public static final int AUDIO_CODEC_NONE = 0; // 0x0
     field public static final int AUDIO_CODEC_QCELP13K = 3; // 0x3
+    field public static final int CAPABILITY_ADD_PARTICIPANT = 67108864; // 0x4000000
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
@@ -43827,6 +43839,7 @@
     field public static final int PROPERTY_ASSISTED_DIALING = 512; // 0x200
     field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 32; // 0x20
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 4; // 0x4
+    field public static final int PROPERTY_IS_ADHOC_CONFERENCE = 4096; // 0x1000
     field public static final int PROPERTY_IS_EXTERNAL_CALL = 16; // 0x10
     field public static final int PROPERTY_IS_RTT = 256; // 0x100
     field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1024; // 0x400
@@ -43922,9 +43935,13 @@
     method public void onConference(android.telecom.Connection, android.telecom.Connection);
     method public void onConnectionServiceFocusGained();
     method public void onConnectionServiceFocusLost();
+    method @Nullable public android.telecom.Conference onCreateIncomingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
+    method public void onCreateIncomingConferenceFailed(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateIncomingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method @Nullable public android.telecom.Conference onCreateOutgoingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
+    method public void onCreateOutgoingConferenceFailed(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateOutgoingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
@@ -44235,6 +44252,7 @@
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall(int);
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
+    method public void addNewIncomingConference(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void cancelMissedCallsNotification();
     method public android.content.Intent createManageBlockedNumbersIntent();
     method @Deprecated @RequiresPermission(android.Manifest.permission.ANSWER_PHONE_CALLS) public boolean endCall();
@@ -44262,6 +44280,7 @@
     method public void registerPhoneAccount(android.telecom.PhoneAccount);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void showInCallScreen(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void silenceRinger();
+    method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void startConference(@NonNull java.util.List<android.net.Uri>, @NonNull android.os.Bundle);
     method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
     field public static final String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
     field public static final String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
@@ -44799,6 +44818,8 @@
     field public static final String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
     field public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
     field public static final String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool";
+    field public static final String KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL = "support_add_conference_participants_bool";
+    field public static final String KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL = "support_adhoc_conference_calls_bool";
     field public static final String KEY_SUPPORT_CLIR_NETWORK_DEFAULT_BOOL = "support_clir_network_default_bool";
     field public static final String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
     field public static final String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt
index 107182c..0282713 100644
--- a/non-updatable-api/module-lib-current.txt
+++ b/non-updatable-api/module-lib-current.txt
@@ -15,5 +15,10 @@
     method public final void markVintfStability();
   }
 
+  public interface Parcelable {
+    field public static final int PARCELABLE_STABILITY_LOCAL = 0; // 0x0
+    field public static final int PARCELABLE_STABILITY_VINTF = 1; // 0x1
+  }
+
 }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 8bfd5f3..d12ba29 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -137,7 +137,7 @@
         // Sending empty PIN here to query the number of remaining PIN attempts
         new CheckSimPin("", mSubId) {
             void onSimCheckResponse(final PinResult result) {
-                Log.d(LOG_TAG, "onSimCheckResponse " + " dummy One result "
+                Log.d(LOG_TAG, "onSimCheckResponse " + " empty One result "
                         + result.toString());
                 if (result.getAttemptsRemaining() >= 0) {
                     mRemainingAttempts = result.getAttemptsRemaining();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index 75cf691..10460da 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -191,7 +191,7 @@
             void onSimLockChangedResponse(final PinResult result) {
                 if (result == null) Log.e(LOG_TAG, "onSimCheckResponse, pin result is NULL");
                 else {
-                    Log.d(LOG_TAG, "onSimCheckResponse " + " dummy One result "
+                    Log.d(LOG_TAG, "onSimCheckResponse " + " empty One result "
                             + result.toString());
                     if (result.getAttemptsRemaining() >= 0) {
                         mRemainingAttempts = result.getAttemptsRemaining();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index a7e7f08..1a5f9b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -265,7 +265,7 @@
 
     /**
      * Set that we are exiting the headsUp pinned mode, but some notifications might still be
-     * animating out. This is used to keep the touchable regions in a sane state.
+     * animating out. This is used to keep the touchable regions in a reasonable state.
      */
     public void setHeadsUpGoingAway(boolean headsUpGoingAway) {
         if (headsUpGoingAway != mHeadsUpGoingAway) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
index f7b8a2e..a791e73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -73,7 +73,9 @@
         val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible &&
                 !statusBarStateController.isDozing
 
-        val shouldListen = onKeyguard || bouncerVisible
+        val userId = KeyguardUpdateMonitor.getCurrentUser()
+        val isFaceEnabled = keyguardUpdateMonitor.isFaceAuthEnabledForUser(userId)
+        val shouldListen = (onKeyguard || bouncerVisible) && isFaceEnabled
         if (shouldListen != isListening) {
             isListening = shouldListen
 
@@ -84,4 +86,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 3a42cd8..173cddc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -397,7 +397,7 @@
             mContentDescriptionFormat = new SimpleDateFormat(format);
             /*
              * Search for an unquoted "a" in the format string, so we can
-             * add dummy characters around it to let us find it again after
+             * add marker characters around it to let us find it again after
              * formatting and change its size.
              */
             if (mAmPmStyle != AM_PM_STYLE_NORMAL) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
index 54502e4..12d0617 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
@@ -198,7 +198,7 @@
         can.drawARGB((int) (frac * 0xFF), 0xDD, 0xEE, 0xAA);
 
         if (DEBUG && size > mSizeMin)
-            // crazy aggressive redrawing here, for debugging only
+            // Very aggressive redrawing here, for debugging only
             mNavigationBarView.postInvalidateDelayed(100);
     }
 }
diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml
index 2b2fe45..e6444f3 100644
--- a/packages/Tethering/AndroidManifest.xml
+++ b/packages/Tethering/AndroidManifest.xml
@@ -24,7 +24,7 @@
     <!-- Permissions must be defined here, and not in the base manifest, as the tethering
          running in the system server process does not need any permission, and having
          privileged permissions added would cause crashes on startup unless they are also
-         added to the privileged permissions whitelist for that package. -->
+         added to the privileged permissions allowlist for that package. -->
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
diff --git a/packages/Tethering/proguard.flags b/packages/Tethering/proguard.flags
index 051fbd1..86b9033 100644
--- a/packages/Tethering/proguard.flags
+++ b/packages/Tethering/proguard.flags
@@ -1,5 +1,5 @@
 # Keep class's integer static field for MessageUtils to parsing their name.
--keep class com.android.networkstack.tethering.Tethering$TetherMasterSM {
+-keep class com.android.networkstack.tethering.Tethering$TetherMainSM {
     static final int CMD_*;
     static final int EVENT_*;
 }
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index a61fcfb..4c155ac 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -196,15 +196,19 @@
     public static final int CMD_TETHER_UNREQUESTED          = BASE_IPSERVER + 2;
     // notification that this interface is down
     public static final int CMD_INTERFACE_DOWN              = BASE_IPSERVER + 3;
-    // notification from the master SM that it had trouble enabling IP Forwarding
+    // notification from the {@link Tethering.TetherMainSM} that it had trouble enabling IP
+    // Forwarding
     public static final int CMD_IP_FORWARDING_ENABLE_ERROR  = BASE_IPSERVER + 4;
-    // notification from the master SM that it had trouble disabling IP Forwarding
+    // notification from the {@link Tethering.TetherMainSM} SM that it had trouble disabling IP
+    // Forwarding
     public static final int CMD_IP_FORWARDING_DISABLE_ERROR = BASE_IPSERVER + 5;
-    // notification from the master SM that it had trouble starting tethering
+    // notification from the {@link Tethering.TetherMainSM} SM that it had trouble starting
+    // tethering
     public static final int CMD_START_TETHERING_ERROR       = BASE_IPSERVER + 6;
-    // notification from the master SM that it had trouble stopping tethering
+    // notification from the {@link Tethering.TetherMainSM} that it had trouble stopping tethering
     public static final int CMD_STOP_TETHERING_ERROR        = BASE_IPSERVER + 7;
-    // notification from the master SM that it had trouble setting the DNS forwarders
+    // notification from the {@link Tethering.TetherMainSM} that it had trouble setting the DNS
+    // forwarders
     public static final int CMD_SET_DNS_FORWARDERS_ERROR    = BASE_IPSERVER + 8;
     // the upstream connection has changed
     public static final int CMD_TETHER_CONNECTION_CHANGED   = BASE_IPSERVER + 9;
@@ -422,9 +426,13 @@
             getHandler().post(() -> {
                 // We are on the handler thread: mDhcpServerStartIndex can be read safely.
                 if (mStartIndex != mDhcpServerStartIndex) {
-                    // This start request is obsolete. When the |server| binder token goes out of
-                    // scope, the garbage collector will finalize it, which causes the network stack
-                    // process garbage collector to collect the server itself.
+                     // This start request is obsolete. Explicitly stop the DHCP server to shut
+                     // down its thread. When the |server| binder token goes out of scope, the
+                     // garbage collector will finalize it, which causes the network stack process
+                     // garbage collector to collect the server itself.
+                    try {
+                        server.stop(null);
+                    } catch (RemoteException e) { }
                     return;
                 }
 
@@ -1315,7 +1323,7 @@
 
     /**
      * This state is terminal for the per interface state machine.  At this
-     * point, the master state machine should have removed this interface
+     * point, the tethering main state machine should have removed this interface
      * specific state machine from its list of possible recipients of
      * tethering requests.  The state machine itself will hang around until
      * the garbage collector finds it.
diff --git a/packages/Tethering/src/android/net/util/TetheringMessageBase.java b/packages/Tethering/src/android/net/util/TetheringMessageBase.java
index 1b763ce..29c0a81 100644
--- a/packages/Tethering/src/android/net/util/TetheringMessageBase.java
+++ b/packages/Tethering/src/android/net/util/TetheringMessageBase.java
@@ -19,7 +19,7 @@
  * This class defines Message.what base addresses for various state machine.
  */
 public class TetheringMessageBase {
-    public static final int BASE_MASTER   = 0;
+    public static final int BASE_MAIN_SM   = 0;
     public static final int BASE_IPSERVER = 100;
 
 }
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
index 9dace70..bb7322f 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
@@ -296,16 +296,16 @@
      * Reference TetheringManager.TETHERING_{@code *} for each tether type.
      *
      * @param config an object that encapsulates the various tethering configuration elements.
-     * Note: this method is only called from TetherMaster on the handler thread.
+     * Note: this method is only called from @{link Tethering.TetherMainSM} on the handler thread.
      * If there are new callers from different threads, the logic should move to
-     * masterHandler to avoid race conditions.
+     * @{link Tethering.TetherMainSM} handler to avoid race conditions.
      */
     public void reevaluateSimCardProvisioning(final TetheringConfiguration config) {
         if (DBG) mLog.i("reevaluateSimCardProvisioning");
 
         if (!mHandler.getLooper().isCurrentThread()) {
             // Except for test, this log should not appear in normal flow.
-            mLog.log("reevaluateSimCardProvisioning() don't run in TetherMaster thread");
+            mLog.log("reevaluateSimCardProvisioning() don't run in TetherMainSM thread");
         }
         mEntitlementCacheValue.clear();
         mCurrentEntitlementResults.clear();
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 3627085..804bb62 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -50,7 +50,7 @@
 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
-import static android.net.util.TetheringMessageBase.BASE_MASTER;
+import static android.net.util.TetheringMessageBase.BASE_MAIN_SM;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
@@ -159,7 +159,7 @@
     private static final boolean VDBG = false;
 
     private static final Class[] sMessageClasses = {
-            Tethering.class, TetherMasterSM.class, IpServer.class
+            Tethering.class, TetherMainSM.class, IpServer.class
     };
     private static final SparseArray<String> sMagicDecoderRing =
             MessageUtils.findMessageNames(sMessageClasses);
@@ -216,7 +216,7 @@
     private final ArrayMap<String, TetherState> mTetherStates;
     private final BroadcastReceiver mStateReceiver;
     private final Looper mLooper;
-    private final StateMachine mTetherMasterSM;
+    private final StateMachine mTetherMainSM;
     private final OffloadController mOffloadController;
     private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
     // TODO: Figure out how to merge this and other downstream-tracking objects
@@ -273,10 +273,10 @@
         mTetherStates = new ArrayMap<>();
         mConnectedClientsTracker = new ConnectedClientsTracker();
 
-        mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper, deps);
-        mTetherMasterSM.start();
+        mTetherMainSM = new TetherMainSM("TetherMain", mLooper, deps);
+        mTetherMainSM.start();
 
-        mHandler = mTetherMasterSM.getHandler();
+        mHandler = mTetherMainSM.getHandler();
         mOffloadController = mDeps.getOffloadController(mHandler, mLog,
                 new OffloadController.Dependencies() {
 
@@ -285,8 +285,8 @@
                         return mConfig;
                     }
                 });
-        mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
-                TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
+        mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMainSM, mLog,
+                TetherMainSM.EVENT_UPSTREAM_CALLBACK);
         mForwardedDownstreams = new LinkedHashSet<>();
 
         IntentFilter filter = new IntentFilter();
@@ -294,8 +294,8 @@
         // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
         // permission is changed according to entitlement check result.
         mEntitlementMgr = mDeps.getEntitlementManager(mContext, mHandler, mLog,
-                () -> mTetherMasterSM.sendMessage(
-                TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
+                () -> mTetherMainSM.sendMessage(
+                TetherMainSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
         mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
             mLog.log("OBSERVED UiEnitlementFailed");
             stopTethering(downstream);
@@ -945,7 +945,7 @@
             }
 
             if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString());
-            mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
+            mTetherMainSM.sendMessage(TetherMainSM.CMD_UPSTREAM_CHANGED);
         }
 
         private void handleUsbAction(Intent intent) {
@@ -1170,7 +1170,7 @@
     private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
         if (TextUtils.isEmpty(ifname)) return;
 
-        disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
+        disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* fake */ 0);
     }
 
     private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
@@ -1381,23 +1381,23 @@
         return false;
     }
 
-    class TetherMasterSM extends StateMachine {
+    class TetherMainSM extends StateMachine {
         // an interface SM has requested Tethering/Local Hotspot
-        static final int EVENT_IFACE_SERVING_STATE_ACTIVE       = BASE_MASTER + 1;
+        static final int EVENT_IFACE_SERVING_STATE_ACTIVE       = BASE_MAIN_SM + 1;
         // an interface SM has unrequested Tethering/Local Hotspot
-        static final int EVENT_IFACE_SERVING_STATE_INACTIVE     = BASE_MASTER + 2;
+        static final int EVENT_IFACE_SERVING_STATE_INACTIVE     = BASE_MAIN_SM + 2;
         // upstream connection change - do the right thing
-        static final int CMD_UPSTREAM_CHANGED                   = BASE_MASTER + 3;
+        static final int CMD_UPSTREAM_CHANGED                   = BASE_MAIN_SM + 3;
         // we don't have a valid upstream conn, check again after a delay
-        static final int CMD_RETRY_UPSTREAM                     = BASE_MASTER + 4;
-        // Events from NetworkCallbacks that we process on the master state
+        static final int CMD_RETRY_UPSTREAM                     = BASE_MAIN_SM + 4;
+        // Events from NetworkCallbacks that we process on the main state
         // machine thread on behalf of the UpstreamNetworkMonitor.
-        static final int EVENT_UPSTREAM_CALLBACK                = BASE_MASTER + 5;
+        static final int EVENT_UPSTREAM_CALLBACK                = BASE_MAIN_SM + 5;
         // we treated the error and want now to clear it
-        static final int CMD_CLEAR_ERROR                        = BASE_MASTER + 6;
-        static final int EVENT_IFACE_UPDATE_LINKPROPERTIES      = BASE_MASTER + 7;
+        static final int CMD_CLEAR_ERROR                        = BASE_MAIN_SM + 6;
+        static final int EVENT_IFACE_UPDATE_LINKPROPERTIES      = BASE_MAIN_SM + 7;
         // Events from EntitlementManager to choose upstream again.
-        static final int EVENT_UPSTREAM_PERMISSION_CHANGED      = BASE_MASTER + 8;
+        static final int EVENT_UPSTREAM_PERMISSION_CHANGED      = BASE_MAIN_SM + 8;
         private final State mInitialState;
         private final State mTetherModeAliveState;
 
@@ -1425,7 +1425,7 @@
 
         private static final int UPSTREAM_SETTLE_TIME_MS     = 10000;
 
-        TetherMasterSM(String name, Looper looper, TetheringDependencies deps) {
+        TetherMainSM(String name, Looper looper, TetheringDependencies deps) {
             super(name, looper);
 
             mInitialState = new InitialState();
@@ -1479,7 +1479,7 @@
             }
         }
 
-        protected boolean turnOnMasterTetherSettings() {
+        protected boolean turnOnMainTetherSettings() {
             final TetheringConfiguration cfg = mConfig;
             try {
                 mNetd.ipfwdEnableForwarding(TAG);
@@ -1506,11 +1506,11 @@
                     return false;
                 }
             }
-            mLog.log("SET master tether settings: ON");
+            mLog.log("SET main tether settings: ON");
             return true;
         }
 
-        protected boolean turnOffMasterTetherSettings() {
+        protected boolean turnOffMainTetherSettings() {
             try {
                 mNetd.tetherStop();
             } catch (RemoteException | ServiceSpecificException e) {
@@ -1526,7 +1526,7 @@
                 return false;
             }
             transitionTo(mInitialState);
-            mLog.log("SET master tether settings: OFF");
+            mLog.log("SET main tether settings: OFF");
             return true;
         }
 
@@ -1730,7 +1730,7 @@
                     // TODO: Re-evaluate possible upstreams. Currently upstream
                     // reevaluation is triggered via received CONNECTIVITY_ACTION
                     // broadcasts that result in being passed a
-                    // TetherMasterSM.CMD_UPSTREAM_CHANGED.
+                    // TetherMainSM.CMD_UPSTREAM_CHANGED.
                     handleNewUpstreamNetworkState(null);
                     break;
                 default:
@@ -1745,9 +1745,9 @@
 
             @Override
             public void enter() {
-                // If turning on master tether settings fails, we have already
+                // If turning on main tether settings fails, we have already
                 // transitioned to an error state; exit early.
-                if (!turnOnMasterTetherSettings()) {
+                if (!turnOnMainTetherSettings()) {
                     return;
                 }
 
@@ -1819,7 +1819,7 @@
                         if (mNotifyList.isEmpty()) {
                             // This transitions us out of TetherModeAliveState,
                             // either to InitialState or an error state.
-                            turnOffMasterTetherSettings();
+                            turnOffMainTetherSettings();
                             break;
                         }
 
@@ -2329,7 +2329,7 @@
         };
     }
 
-    // TODO: Move into TetherMasterSM.
+    // TODO: Move into TetherMainSM.
     private void notifyInterfaceStateChange(IpServer who, int state, int error) {
         final String iface = who.interfaceName();
         synchronized (mPublicSync) {
@@ -2344,27 +2344,27 @@
 
         mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error));
 
-        // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
-        // Thus we give a chance for TetherMasterSM to recover to InitialState
+        // If TetherMainSM is in ErrorState, TetherMainSM stays there.
+        // Thus we give a chance for TetherMainSM to recover to InitialState
         // by sending CMD_CLEAR_ERROR
         if (error == TETHER_ERROR_INTERNAL_ERROR) {
-            mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
+            mTetherMainSM.sendMessage(TetherMainSM.CMD_CLEAR_ERROR, who);
         }
         int which;
         switch (state) {
             case IpServer.STATE_UNAVAILABLE:
             case IpServer.STATE_AVAILABLE:
-                which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
+                which = TetherMainSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
                 break;
             case IpServer.STATE_TETHERED:
             case IpServer.STATE_LOCAL_ONLY:
-                which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
+                which = TetherMainSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
                 break;
             default:
                 Log.wtf(TAG, "Unknown interface state: " + state);
                 return;
         }
-        mTetherMasterSM.sendMessage(which, state, 0, who);
+        mTetherMainSM.sendMessage(which, state, 0, who);
         sendTetherStateChangedBroadcast();
     }
 
@@ -2384,8 +2384,8 @@
         mLog.log(String.format(
                 "OBSERVED LinkProperties update iface=%s state=%s lp=%s",
                 iface, IpServer.getStateString(state), newLp));
-        final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
-        mTetherMasterSM.sendMessage(which, state, 0, newLp);
+        final int which = TetherMainSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
+        mTetherMainSM.sendMessage(which, state, 0, newLp);
     }
 
     private void maybeTrackNewInterfaceLocked(final String iface) {
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
index 320427c..b17065c 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
@@ -63,7 +63,7 @@
  * Calling #registerMobileNetworkRequest() to bring up mobile DUN/HIPRI network.
  *
  * The methods and data members of this class are only to be accessed and
- * modified from the tethering master state machine thread. Any other
+ * modified from the tethering main state machine thread. Any other
  * access semantics would necessitate the addition of locking.
  *
  * TODO: Move upstream selection logic here.
diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 05cf58a..e0a1dc7 100644
--- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -49,6 +49,7 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.inOrder;
@@ -72,6 +73,7 @@
 import android.net.RouteInfo;
 import android.net.TetherOffloadRuleParcel;
 import android.net.TetherStatsParcel;
+import android.net.dhcp.DhcpServerCallbacks;
 import android.net.dhcp.DhcpServingParamsParcel;
 import android.net.dhcp.IDhcpEventCallbacks;
 import android.net.dhcp.IDhcpServer;
@@ -162,17 +164,6 @@
 
     private void initStateMachine(int interfaceType, boolean usingLegacyDhcp,
             boolean usingBpfOffload) throws Exception {
-        doAnswer(inv -> {
-            final IDhcpServerCallbacks cb = inv.getArgument(2);
-            new Thread(() -> {
-                try {
-                    cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
-                } catch (RemoteException e) {
-                    fail(e.getMessage());
-                }
-            }).run();
-            return null;
-        }).when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(), any());
         when(mDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon);
         when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS);
 
@@ -224,6 +215,20 @@
         when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(mTestAddress);
     }
 
+    private void setUpDhcpServer() throws Exception {
+        doAnswer(inv -> {
+            final IDhcpServerCallbacks cb = inv.getArgument(2);
+            new Thread(() -> {
+                try {
+                    cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
+                } catch (RemoteException e) {
+                    fail(e.getMessage());
+                }
+            }).run();
+            return null;
+        }).when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(), any());
+    }
+
     @Before public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog);
@@ -257,6 +262,8 @@
                         return mTetherConfig;
                     }
                 }));
+
+        setUpDhcpServer();
     }
 
     @Test
@@ -964,6 +971,31 @@
         reset(mRaDaemon);
     }
 
+    @Test
+    public void testStopObsoleteDhcpServer() throws Exception {
+        final ArgumentCaptor<DhcpServerCallbacks> cbCaptor =
+                ArgumentCaptor.forClass(DhcpServerCallbacks.class);
+        doNothing().when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(),
+                cbCaptor.capture());
+        initStateMachine(TETHERING_WIFI);
+        dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
+        verify(mDhcpServer, never()).startWithCallbacks(any(), any());
+
+        // No stop dhcp server because dhcp server is not created yet.
+        dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED);
+        verify(mDhcpServer, never()).stop(any());
+
+        // Stop obsolete dhcp server.
+        try {
+            final DhcpServerCallbacks cb = cbCaptor.getValue();
+            cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
+            mLooper.dispatchAll();
+        } catch (RemoteException e) {
+            fail(e.getMessage());
+        }
+        verify(mDhcpServer).stop(any());
+    }
+
     private void assertDhcpServingParams(final DhcpServingParamsParcel params,
             final IpPrefix prefix) {
         // Last address byte is random
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index d37aad2..e255737 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -337,11 +337,11 @@
     }
 
     public class MockTetheringDependencies extends TetheringDependencies {
-        StateMachine mUpstreamNetworkMonitorMasterSM;
+        StateMachine mUpstreamNetworkMonitorSM;
         ArrayList<IpServer> mIpv6CoordinatorNotifyList;
 
         public void reset() {
-            mUpstreamNetworkMonitorMasterSM = null;
+            mUpstreamNetworkMonitorSM = null;
             mIpv6CoordinatorNotifyList = null;
         }
 
@@ -368,7 +368,7 @@
         @Override
         public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
                 StateMachine target, SharedLog log, int what) {
-            mUpstreamNetworkMonitorMasterSM = target;
+            mUpstreamNetworkMonitorSM = target;
             return mUpstreamNetworkMonitor;
         }
 
@@ -911,8 +911,8 @@
         initTetheringUpstream(upstreamState);
 
         // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
-        mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
-                Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+        mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage(
+                Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK,
                 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
                 0,
                 upstreamState);
@@ -1126,7 +1126,7 @@
         verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
         // This never gets called because of the exception thrown above.
         verify(mNetd, times(0)).tetherStartWithConfiguration(any());
-        // When the master state machine transitions to an error state it tells
+        // When the main state machine transitions to an error state it tells
         // downstream interfaces, which causes us to tell Wi-Fi about the error
         // so it can take down AP mode.
         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
@@ -1753,8 +1753,8 @@
 
     @Test
     public void testUpstreamNetworkChanged() {
-        final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
-                mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
+        final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM)
+                mTetheringDependencies.mUpstreamNetworkMonitorSM;
         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
         initTetheringUpstream(upstreamState);
         stateMachine.chooseUpstreamType(true);
@@ -1765,8 +1765,8 @@
 
     @Test
     public void testUpstreamCapabilitiesChanged() {
-        final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
-                mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
+        final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM)
+                mTetheringDependencies.mUpstreamNetworkMonitorSM;
         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
         initTetheringUpstream(upstreamState);
         stateMachine.chooseUpstreamType(true);
@@ -1891,8 +1891,8 @@
                 any(), any());
         reset(mNetd, mUsbManager);
         upstreamNetwork = buildV4WifiUpstreamState(ipv4Address, 30, wifiNetwork);
-        mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
-                Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+        mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage(
+                Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK,
                 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
                 0,
                 upstreamNetwork);
@@ -1929,8 +1929,8 @@
 
         final UpstreamNetworkState upstreamNetwork = buildV4WifiUpstreamState(
                 upstreamAddress, 16, wifiNetwork);
-        mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
-                Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+        mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage(
+                Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK,
                 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
                 0,
                 upstreamNetwork);
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 4f49fb7..f35d334 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -228,7 +228,7 @@
         if (connected) {
             synchronized (mLock) {
                 if (mZombie) {
-                    // Sanity check - shouldn't happen
+                    // Validation check - shouldn't happen
                     if (mRemoteService == null) {
                         Slog.w(TAG, "Cannot resurrect sessions because remote service is null");
                         return;
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index ce2bc82..7d7c570 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1379,7 +1379,7 @@
                 if ((state & ViewState.STATE_AUTOFILLED_ONCE) != 0) {
                     final String datasetId = viewState.getDatasetId();
                     if (datasetId == null) {
-                        // Sanity check - should never happen.
+                        // Validation check - should never happen.
                         Slog.w(TAG, "logContextCommitted(): no dataset id on " + viewState);
                         continue;
                     }
@@ -1513,7 +1513,7 @@
         final ArrayMap<String, String> algorithms = userData.getFieldClassificationAlgorithms();
         final ArrayMap<String, Bundle> args = userData.getFieldClassificationArgs();
 
-        // Sanity check
+        // Validation check
         if (userValues == null || categoryIds == null || userValues.length != categoryIds.length) {
             final int valuesLength = userValues == null ? -1 : userValues.length;
             final int idsLength = categoryIds == null ? -1 : categoryIds.length;
@@ -2312,12 +2312,12 @@
                     final String currentUrl = mUrlBar == null ? null
                             : mUrlBar.getText().toString().trim();
                     if (currentUrl == null) {
-                        // Sanity check - shouldn't happen.
+                        // Validation check - shouldn't happen.
                         wtf(null, "URL bar value changed, but current value is null");
                         return;
                     }
                     if (value == null || ! value.isText()) {
-                        // Sanity check - shouldn't happen.
+                        // Validation check - shouldn't happen.
                         wtf(null, "URL bar value changed to null or non-text: %s", value);
                         return;
                     }
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 2aa15d0..e258735 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -54,6 +54,7 @@
         "android.hardware.contexthub-V1.0-java",
         "android.hidl.manager-V1.2-java",
         "dnsresolver_aidl_interface-java",
+        "icu4j_calendar_astronomer",
         "netd_aidl_interfaces-platform-java",
     ],
 }
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index a75a80a..f8774b1 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -21,14 +21,23 @@
 import static android.Manifest.permission.INTERNET;
 import static android.Manifest.permission.NETWORK_STACK;
 import static android.Manifest.permission.UPDATE_DEVICE_STATS;
-import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.net.INetd.PERMISSION_INTERNET;
+import static android.net.INetd.PERMISSION_NETWORK;
+import static android.net.INetd.PERMISSION_NONE;
+import static android.net.INetd.PERMISSION_SYSTEM;
+import static android.net.INetd.PERMISSION_UNINSTALLED;
+import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.os.Process.INVALID_UID;
 import static android.os.Process.SYSTEM_UID;
 
+import static com.android.internal.util.ArrayUtils.convertToIntArray;
+
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -51,7 +60,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.SystemConfig;
@@ -65,7 +73,6 @@
 import java.util.Map.Entry;
 import java.util.Set;
 
-
 /**
  * A utility class to inform Netd of UID permisisons.
  * Does a mass update at boot and then monitors for app install/remove.
@@ -114,6 +121,13 @@
         public int getDeviceFirstSdkInt() {
             return Build.VERSION.FIRST_SDK_INT;
         }
+
+        /**
+         * Check whether given uid has specific permission.
+         */
+        public int uidPermission(@NonNull final String permission, final int uid) {
+            return ActivityManager.checkUidPermission(permission, uid);
+        }
     }
 
     public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) {
@@ -156,8 +170,9 @@
             }
             mAllApps.add(UserHandle.getAppId(uid));
 
-            boolean isNetwork = hasNetworkPermission(app);
-            boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
+            final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid);
+            final boolean hasRestrictedPermission =
+                    hasRestrictedNetworkPermission(app.applicationInfo);
 
             if (isNetwork || hasRestrictedPermission) {
                 Boolean permission = mApps.get(uid);
@@ -169,8 +184,7 @@
             }
 
             //TODO: unify the management of the permissions into one codepath.
-            int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
-                    app.requestedPermissionsFlags);
+            final int otherNetdPerms = getNetdPermissionMask(uid);
             netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
         }
 
@@ -190,9 +204,8 @@
             // Get the uids of native services that have UPDATE_DEVICE_STATS or INTERNET permission.
             if (perms != null) {
                 netdPermission |= perms.contains(UPDATE_DEVICE_STATS)
-                        ? INetd.PERMISSION_UPDATE_DEVICE_STATS : 0;
-                netdPermission |= perms.contains(INTERNET)
-                        ? INetd.PERMISSION_INTERNET : 0;
+                        ? PERMISSION_UPDATE_DEVICE_STATS : 0;
+                netdPermission |= perms.contains(INTERNET) ? PERMISSION_INTERNET : 0;
             }
             netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
         }
@@ -207,48 +220,33 @@
     }
 
     @VisibleForTesting
-    boolean hasPermission(@NonNull final PackageInfo app, @NonNull final String permission) {
-        if (app.requestedPermissions == null || app.requestedPermissionsFlags == null) {
-            return false;
-        }
-        final int index = ArrayUtils.indexOf(app.requestedPermissions, permission);
-        if (index < 0 || index >= app.requestedPermissionsFlags.length) return false;
-        return (app.requestedPermissionsFlags[index] & REQUESTED_PERMISSION_GRANTED) != 0;
+    boolean hasPermission(@NonNull final String permission, final int uid) {
+        return mDeps.uidPermission(permission, uid) == PackageManager.PERMISSION_GRANTED;
     }
 
     @VisibleForTesting
-    boolean hasNetworkPermission(@NonNull final PackageInfo app) {
-        return hasPermission(app, CHANGE_NETWORK_STATE);
-    }
-
-    @VisibleForTesting
-    boolean hasRestrictedNetworkPermission(@NonNull final PackageInfo app) {
-        // TODO : remove this check in the future(b/31479477). All apps should just
+    boolean hasRestrictedNetworkPermission(@Nullable final ApplicationInfo appInfo) {
+        if (appInfo == null)  return false;
+        // TODO : remove this check in the future(b/162295056). All apps should just
         // request the appropriate permission for their use case since android Q.
-        if (app.applicationInfo != null) {
-            // Backward compatibility for b/114245686, on devices that launched before Q daemons
-            // and apps running as the system UID are exempted from this check.
-            if (app.applicationInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q) {
-                return true;
-            }
-
-            if (app.applicationInfo.targetSdkVersion < VERSION_Q
-                    && isVendorApp(app.applicationInfo)) {
-                return true;
-            }
+        if ((appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo))
+                // Backward compatibility for b/114245686, on devices that launched before Q daemons
+                // and apps running as the system UID are exempted from this check.
+                || (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q)) {
+            return true;
         }
 
-        return hasPermission(app, PERMISSION_MAINLINE_NETWORK_STACK)
-                || hasPermission(app, NETWORK_STACK)
-                || hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+        return hasPermission(PERMISSION_MAINLINE_NETWORK_STACK, appInfo.uid)
+                || hasPermission(NETWORK_STACK, appInfo.uid)
+                || hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, appInfo.uid);
     }
 
     /** Returns whether the given uid has using background network permission. */
     public synchronized boolean hasUseBackgroundNetworksPermission(final int uid) {
         // Apps with any of the CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_INTERNAL or
         // CONNECTIVITY_USE_RESTRICTED_NETWORKS permission has the permission to use background
-        // networks. mApps contains the result of checks for both hasNetworkPermission and
-        // hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of
+        // networks. mApps contains the result of checks for both CHANGE_NETWORK_STATE permission
+        // and hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of
         // permissions at least.
         return mApps.containsKey(uid);
     }
@@ -273,11 +271,11 @@
         }
         try {
             if (add) {
-                mNetd.networkSetPermissionForUser(INetd.PERMISSION_NETWORK, toIntArray(network));
-                mNetd.networkSetPermissionForUser(INetd.PERMISSION_SYSTEM, toIntArray(system));
+                mNetd.networkSetPermissionForUser(PERMISSION_NETWORK, convertToIntArray(network));
+                mNetd.networkSetPermissionForUser(PERMISSION_SYSTEM, convertToIntArray(system));
             } else {
-                mNetd.networkClearPermissionForUser(toIntArray(network));
-                mNetd.networkClearPermissionForUser(toIntArray(system));
+                mNetd.networkClearPermissionForUser(convertToIntArray(network));
+                mNetd.networkClearPermissionForUser(convertToIntArray(system));
             }
         } catch (RemoteException e) {
             loge("Exception when updating permissions: " + e);
@@ -323,14 +321,15 @@
     }
 
     @VisibleForTesting
-    protected Boolean highestPermissionForUid(Boolean currentPermission, String name) {
+    protected Boolean highestPermissionForUid(Boolean currentPermission, String name, int uid) {
         if (currentPermission == SYSTEM) {
             return currentPermission;
         }
         try {
             final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS);
-            final boolean isNetwork = hasNetworkPermission(app);
-            final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
+            final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid);
+            final boolean hasRestrictedPermission =
+                    hasRestrictedNetworkPermission(app.applicationInfo);
             if (isNetwork || hasRestrictedPermission) {
                 currentPermission = hasRestrictedPermission;
             }
@@ -342,23 +341,14 @@
     }
 
     private int getPermissionForUid(final int uid) {
-        int permission = INetd.PERMISSION_NONE;
         // Check all the packages for this UID. The UID has the permission if any of the
         // packages in it has the permission.
         final String[] packages = mPackageManager.getPackagesForUid(uid);
-        if (packages != null && packages.length > 0) {
-            for (String name : packages) {
-                final PackageInfo app = getPackageInfo(name);
-                if (app != null && app.requestedPermissions != null) {
-                    permission |= getNetdPermissionMask(app.requestedPermissions,
-                            app.requestedPermissionsFlags);
-                }
-            }
-        } else {
+        if (packages == null || packages.length <= 0) {
             // The last package of this uid is removed from device. Clean the package up.
-            permission = INetd.PERMISSION_UNINSTALLED;
+            return PERMISSION_UNINSTALLED;
         }
-        return permission;
+        return getNetdPermissionMask(uid);
     }
 
     /**
@@ -375,7 +365,7 @@
 
         // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
         // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
-        final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName);
+        final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName, uid);
         if (permission != mApps.get(uid)) {
             mApps.put(uid, permission);
 
@@ -431,7 +421,7 @@
         String[] packages = mPackageManager.getPackagesForUid(uid);
         if (packages != null && packages.length > 0) {
             for (String name : packages) {
-                permission = highestPermissionForUid(permission, name);
+                permission = highestPermissionForUid(permission, name, uid);
                 if (permission == SYSTEM) {
                     // An app with this UID still has the SYSTEM permission.
                     // Therefore, this UID must already have the SYSTEM permission.
@@ -467,19 +457,13 @@
         sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
     }
 
-    private static int getNetdPermissionMask(String[] requestedPermissions,
-                                             int[] requestedPermissionsFlags) {
-        int permissions = 0;
-        if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions;
-        for (int i = 0; i < requestedPermissions.length; i++) {
-            if (requestedPermissions[i].equals(INTERNET)
-                    && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
-                permissions |= INetd.PERMISSION_INTERNET;
-            }
-            if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS)
-                    && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
-                permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
-            }
+    private int getNetdPermissionMask(final int uid) {
+        int permissions = PERMISSION_NONE;
+        if (hasPermission(INTERNET, uid)) {
+            permissions |= PERMISSION_INTERNET;
+        }
+        if (hasPermission(UPDATE_DEVICE_STATS, uid)) {
+            permissions |= PERMISSION_UPDATE_DEVICE_STATS;
         }
         return permissions;
     }
@@ -648,19 +632,19 @@
         for (int i = 0; i < netdPermissionsAppIds.size(); i++) {
             int permissions = netdPermissionsAppIds.valueAt(i);
             switch(permissions) {
-                case (INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS):
+                case (PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS):
                     allPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
                     break;
-                case INetd.PERMISSION_INTERNET:
+                case PERMISSION_INTERNET:
                     internetPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
                     break;
-                case INetd.PERMISSION_UPDATE_DEVICE_STATS:
+                case PERMISSION_UPDATE_DEVICE_STATS:
                     updateStatsPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
                     break;
-                case INetd.PERMISSION_NONE:
+                case PERMISSION_NONE:
                     noPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
                     break;
-                case INetd.PERMISSION_UNINSTALLED:
+                case PERMISSION_UNINSTALLED:
                     uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i));
                 default:
                     Log.e(TAG, "unknown permission type: " + permissions + "for uid: "
@@ -671,24 +655,24 @@
             // TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids()
             if (allPermissionAppIds.size() != 0) {
                 mNetd.trafficSetNetPermForUids(
-                        INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
-                        ArrayUtils.convertToIntArray(allPermissionAppIds));
+                        PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS,
+                        convertToIntArray(allPermissionAppIds));
             }
             if (internetPermissionAppIds.size() != 0) {
-                mNetd.trafficSetNetPermForUids(INetd.PERMISSION_INTERNET,
-                        ArrayUtils.convertToIntArray(internetPermissionAppIds));
+                mNetd.trafficSetNetPermForUids(PERMISSION_INTERNET,
+                        convertToIntArray(internetPermissionAppIds));
             }
             if (updateStatsPermissionAppIds.size() != 0) {
-                mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UPDATE_DEVICE_STATS,
-                        ArrayUtils.convertToIntArray(updateStatsPermissionAppIds));
+                mNetd.trafficSetNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS,
+                        convertToIntArray(updateStatsPermissionAppIds));
             }
             if (noPermissionAppIds.size() != 0) {
-                mNetd.trafficSetNetPermForUids(INetd.PERMISSION_NONE,
-                        ArrayUtils.convertToIntArray(noPermissionAppIds));
+                mNetd.trafficSetNetPermForUids(PERMISSION_NONE,
+                        convertToIntArray(noPermissionAppIds));
             }
             if (uninstalledAppIds.size() != 0) {
-                mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UNINSTALLED,
-                        ArrayUtils.convertToIntArray(uninstalledAppIds));
+                mNetd.trafficSetNetPermForUids(PERMISSION_UNINSTALLED,
+                        convertToIntArray(uninstalledAppIds));
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Pass appId list of special permission failed." + e);
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index ab52523..ba3cea7 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -28,6 +28,7 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_REMOVED;
+import static android.net.NetworkUtils.multiplySafeByRational;
 import static android.text.format.DateUtils.WEEK_IN_MILLIS;
 
 import static com.android.server.net.NetworkStatsService.TAG;
@@ -185,35 +186,6 @@
         }
     }
 
-    /**
-     * Safely multiple a value by a rational.
-     * <p>
-     * Internally it uses integer-based math whenever possible, but switches
-     * over to double-based math if values would overflow.
-     */
-    @VisibleForTesting
-    public static long multiplySafe(long value, long num, long den) {
-        if (den == 0) den = 1;
-        long x = value;
-        long y = num;
-
-        // Logic shamelessly borrowed from Math.multiplyExact()
-        long r = x * y;
-        long ax = Math.abs(x);
-        long ay = Math.abs(y);
-        if (((ax | ay) >>> 31 != 0)) {
-            // Some bits greater than 2^31 that might cause overflow
-            // Check the result using the divide operator
-            // and check for the special case of Long.MIN_VALUE * -1
-            if (((y != 0) && (r / y != x)) ||
-                    (x == Long.MIN_VALUE && y == -1)) {
-                // Use double math to avoid overflowing
-                return (long) (((double) num / den) * value);
-            }
-        }
-        return r / den;
-    }
-
     public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel) {
         return getRelevantUids(accessLevel, Binder.getCallingUid());
     }
@@ -311,11 +283,13 @@
             }
 
             final long rawBytes = entry.rxBytes + entry.txBytes;
-            final long rawRxBytes = entry.rxBytes;
-            final long rawTxBytes = entry.txBytes;
+            final long rawRxBytes = entry.rxBytes == 0 ? 1 : entry.rxBytes;
+            final long rawTxBytes = entry.txBytes == 0 ? 1 : entry.txBytes;
             final long targetBytes = augmentPlan.getDataUsageBytes();
-            final long targetRxBytes = multiplySafe(targetBytes, rawRxBytes, rawBytes);
-            final long targetTxBytes = multiplySafe(targetBytes, rawTxBytes, rawBytes);
+
+            final long targetRxBytes = multiplySafeByRational(targetBytes, rawRxBytes, rawBytes);
+            final long targetTxBytes = multiplySafeByRational(targetBytes, rawTxBytes, rawBytes);
+
 
             // Scale all matching buckets to reach anchor target
             final long beforeTotal = combined.getTotalBytes();
@@ -323,8 +297,10 @@
                 combined.getValues(i, entry);
                 if (entry.bucketStart >= augmentStart
                         && entry.bucketStart + entry.bucketDuration <= augmentEnd) {
-                    entry.rxBytes = multiplySafe(targetRxBytes, entry.rxBytes, rawRxBytes);
-                    entry.txBytes = multiplySafe(targetTxBytes, entry.txBytes, rawTxBytes);
+                    entry.rxBytes = multiplySafeByRational(
+                            targetRxBytes, entry.rxBytes, rawRxBytes);
+                    entry.txBytes = multiplySafeByRational(
+                            targetTxBytes, entry.txBytes, rawTxBytes);
                     // We purposefully clear out packet counters to indicate
                     // that this data has been augmented.
                     entry.rxPackets = 0;
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 86ad0b3..e9868fd 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -59,7 +59,7 @@
     private static final String TAG = "NetworkStatsFactory";
 
     private static final boolean USE_NATIVE_PARSING = true;
-    private static final boolean SANITY_CHECK_NATIVE = false;
+    private static final boolean VALIDATE_NATIVE_STATS = false;
 
     /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */
     private final File mStatsXtIfaceAll;
@@ -347,7 +347,7 @@
                             INTERFACES_ALL, TAG_ALL, mUseBpfStats) != 0) {
                         throw new IOException("Failed to parse network stats");
                     }
-                    if (SANITY_CHECK_NATIVE) {
+                    if (VALIDATE_NATIVE_STATS) {
                         final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid,
                                 UID_ALL, INTERFACES_ALL, TAG_ALL);
                         assertEquals(javaStats, stats);
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index a94a2f7..66eda1f 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -227,7 +227,7 @@
         for (int i = 0; i < delta.size(); i++) {
             entry = delta.getValues(i, entry);
 
-            // As a last-ditch sanity check, report any negative values and
+            // As a last-ditch check, report any negative values and
             // clamp them so recording below doesn't croak.
             if (entry.isNegative()) {
                 if (mObserver != null) {
diff --git a/services/core/java/com/android/server/twilight/TwilightService.java b/services/core/java/com/android/server/twilight/TwilightService.java
index e4cb19e..9464dbf 100644
--- a/services/core/java/com/android/server/twilight/TwilightService.java
+++ b/services/core/java/com/android/server/twilight/TwilightService.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.icu.impl.CalendarAstronomer;
 import android.icu.util.Calendar;
 import android.location.Location;
 import android.location.LocationListener;
@@ -37,6 +36,8 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.SystemService;
 
+import com.ibm.icu.impl.CalendarAstronomer;
+
 import java.util.Objects;
 
 /**
diff --git a/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp b/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp
index 503f0cf..3dfce3a 100644
--- a/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp
+++ b/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp
@@ -235,7 +235,7 @@
         return 0;
     }
 
-    // Sanity check - remove
+    // Soundness check - remove
     if (gContext.device->notify != hal_notify_callback) {
         ALOGE("NOTIFY not set properly: %p != %p", gContext.device->notify, hal_notify_callback);
     }
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 749258e..0e30f93 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -921,7 +921,7 @@
                     contaminantDetectionStatus);
             mPorts.put(portId, portInfo);
         } else {
-            // Sanity check that ports aren't changing definition out from under us.
+            // Validate that ports aren't changing definition out from under us.
             if (supportedModes != portInfo.mUsbPort.getSupportedModes()) {
                 logAndPrint(Log.WARN, pw, "Ignoring inconsistent list of supported modes from "
                         + "USB port driver (should be immutable): "
diff --git a/startop/OWNERS b/startop/OWNERS
index 5cf9582..3394be9 100644
--- a/startop/OWNERS
+++ b/startop/OWNERS
@@ -4,3 +4,4 @@
 iam@google.com
 mathieuc@google.com
 sehr@google.com
+yawanng@google.com
diff --git a/telecomm/TEST_MAPPING b/telecomm/TEST_MAPPING
index d585666..c9903f9 100644
--- a/telecomm/TEST_MAPPING
+++ b/telecomm/TEST_MAPPING
@@ -23,6 +23,14 @@
           "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
+    },
+    {
+      "name": "CtsTelecomTestCases",
+      "options": [
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
     }
   ]
 }
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index ead90bb..8b89412 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -461,8 +461,8 @@
 
         /**
          * Call supports adding participants to the call via
-         * {@link #addConferenceParticipants(List)}.
-         * @hide
+         * {@link #addConferenceParticipants(List)}. Once participants are added, the call becomes
+         * an adhoc conference call ({@link #PROPERTY_IS_ADHOC_CONFERENCE}).
          */
         public static final int CAPABILITY_ADD_PARTICIPANT = 0x02000000;
 
@@ -598,8 +598,11 @@
 
         /**
          * Indicates that the call is an adhoc conference call. This property can be set for both
-         * incoming and outgoing calls.
-         * @hide
+         * incoming and outgoing calls. An adhoc conference call is formed using
+         * {@link #addConferenceParticipants(List)},
+         * {@link TelecomManager#addNewIncomingConference(PhoneAccountHandle, Bundle)}, or
+         * {@link TelecomManager#startConference(List, Bundle)}, rather than by merging existing
+         * call using {@link #conference(Call)}.
          */
         public static final int PROPERTY_IS_ADHOC_CONFERENCE = 0x00002000;
 
@@ -1766,7 +1769,6 @@
      * See {@link Details#CAPABILITY_ADD_PARTICIPANT}.
      *
      * @param participants participants to be pulled to existing call.
-     * @hide
      */
     public void addConferenceParticipants(@NonNull List<Uri> participants) {
         mInCallAdapter.addConferenceParticipants(mTelecomCallId, participants);
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index d960552..39c3ff9 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -181,8 +181,8 @@
 
     /**
      * Returns whether this conference is requesting that the system play a ringback tone
-     * on its behalf.
-     * @hide
+     * on its behalf. A ringback tone may be played when an outgoing conference is in the process of
+     * connecting to give the user an audible indication of that process.
      */
     public final boolean isRingbackRequested() {
         return mRingbackRequested;
@@ -329,7 +329,6 @@
     /**
      * Notifies the {@link Conference} of a request to add a new participants to the conference call
      * @param participants that will be added to this conference call
-     * @hide
      */
     public void onAddConferenceParticipants(@NonNull List<Uri> participants) {}
 
@@ -340,7 +339,6 @@
      * the default dialer's {@link InCallService}.
      *
      * @param videoState The video state in which to answer the connection.
-     * @hide
      */
     public void onAnswer(int videoState) {}
 
@@ -360,7 +358,6 @@
      * a request to reject.
      * For managed {@link ConnectionService}s, this will be called when the user rejects a call via
      * the default dialer's {@link InCallService}.
-     * @hide
      */
     public void onReject() {}
 
@@ -380,7 +377,6 @@
 
     /**
      * Sets state to be ringing.
-     * @hide
      */
     public final void setRinging() {
         setState(Connection.STATE_RINGING);
@@ -506,7 +502,6 @@
      * that do not play a ringback tone themselves in the conference's audio stream.
      *
      * @param ringback Whether the ringback tone is to be played.
-     * @hide
      */
     public final void setRingbackRequested(boolean ringback) {
         if (mRingbackRequested != ringback) {
@@ -773,7 +768,6 @@
      *
      * @param disconnectCause The disconnect cause, ({@see android.telecomm.DisconnectCause}).
      * @return A {@code Conference} which indicates failure.
-     * @hide
      */
     public @NonNull static Conference createFailedConference(
             @NonNull DisconnectCause disconnectCause, @NonNull PhoneAccountHandle phoneAccount) {
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 9dfa3ac..b354521 100755
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -383,8 +383,10 @@
 
     /**
      * When set, indicates that this {@link Connection} supports initiation of a conference call
-     * by directly adding participants using {@link #onAddConferenceParticipants(List)}.
-     * @hide
+     * by directly adding participants using {@link #onAddConferenceParticipants(List)}. When
+     * participants are added to a {@link Connection}, it will be replaced by a {@link Conference}
+     * instance with {@link #PROPERTY_IS_ADHOC_CONFERENCE} set to indicate that it is an adhoc
+     * conference call.
      */
     public static final int CAPABILITY_ADD_PARTICIPANT = 0x04000000;
 
@@ -526,10 +528,9 @@
     public static final int PROPERTY_REMOTELY_HOSTED = 1 << 11;
 
     /**
-     * Set by the framework to indicate that it is an adhoc conference call.
+     * Set by the framework to indicate that a call is an adhoc conference call.
      * <p>
-     * This is used for Outgoing and incoming conference calls.
-     * @hide
+     * This is used for outgoing and incoming conference calls.
      */
     public static final int PROPERTY_IS_ADHOC_CONFERENCE = 1 << 12;
 
@@ -3009,7 +3010,6 @@
      * Supports initiation of a conference call by directly adding participants to an ongoing call.
      *
      * @param participants with which conference call will be formed.
-     * @hide
      */
     public void onAddConferenceParticipants(@NonNull List<Uri> participants) {}
 
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 1b60e48..95c238e 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -2638,15 +2638,15 @@
         return null;
     }
     /**
-     * Create a {@code Connection} given an incoming request. This is used to attach to existing
-     * incoming conference call.
+     * Create a {@code Conference} given an incoming request. This is used to attach to an incoming
+     * conference call initiated via
+     * {@link TelecomManager#addNewIncomingConference(PhoneAccountHandle, Bundle)}.
      *
      * @param connectionManagerPhoneAccount See description at
      *         {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
-     * @param request Details about the incoming call.
-     * @return The {@code Connection} object to satisfy this call, or {@code null} to
+     * @param request Details about the incoming conference call.
+     * @return The {@code Conference} object to satisfy this call, or {@code null} to
      *         not handle the call.
-     * @hide
      */
     public @Nullable Conference onCreateIncomingConference(
             @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
@@ -2731,7 +2731,6 @@
      * @param connectionManagerPhoneAccount See description at
      *         {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
      * @param request The incoming connection request.
-     * @hide
      */
     public void onCreateIncomingConferenceFailed(
             @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
@@ -2752,7 +2751,6 @@
      * @param connectionManagerPhoneAccount See description at
      *         {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
      * @param request The outgoing connection request.
-     * @hide
      */
     public void onCreateOutgoingConferenceFailed(
             @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
@@ -2801,7 +2799,8 @@
 
     /**
      * Create a {@code Conference} given an outgoing request. This is used to initiate new
-     * outgoing conference call.
+     * outgoing conference call requested via
+     * {@link TelecomManager#startConference(List, Bundle)}.
      *
      * @param connectionManagerPhoneAccount The connection manager account to use for managing
      *         this call.
@@ -2821,7 +2820,6 @@
      * @param request Details about the outgoing call.
      * @return The {@code Conference} object to satisfy this call, or the result of an invocation
      *         of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
-     * @hide
      */
     public @Nullable Conference onCreateOutgoingConference(
             @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index b3bf507..15b26dc 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1850,11 +1850,13 @@
 
     /**
      * Registers a new incoming conference. A {@link ConnectionService} should invoke this method
-     * when it has an incoming conference. For managed {@link ConnectionService}s, the specified
-     * {@link PhoneAccountHandle} must have been registered with {@link #registerPhoneAccount} and
-     * the user must have enabled the corresponding {@link PhoneAccount}.  This can be checked using
-     * {@link #getPhoneAccount}. Self-managed {@link ConnectionService}s must have
-     * {@link android.Manifest.permission#MANAGE_OWN_CALLS} to add a new incoming call.
+     * when it has an incoming conference. An incoming {@link Conference} is an adhoc conference
+     * call initiated on another device which the user is being invited to join in. For managed
+     * {@link ConnectionService}s, the specified {@link PhoneAccountHandle} must have been
+     * registered with {@link #registerPhoneAccount} and the user must have enabled the
+     * corresponding {@link PhoneAccount}.  This can be checked using
+     * {@link #getPhoneAccount(PhoneAccountHandle)}. Self-managed {@link ConnectionService}s must
+     * have {@link android.Manifest.permission#MANAGE_OWN_CALLS} to add a new incoming call.
      * <p>
      * The incoming conference you are adding is assumed to have a video state of
      * {@link VideoProfile#STATE_AUDIO_ONLY}, unless the extra value
@@ -1862,8 +1864,9 @@
      * <p>
      * Once invoked, this method will cause the system to bind to the {@link ConnectionService}
      * associated with the {@link PhoneAccountHandle} and request additional information about the
-     * call (See {@link ConnectionService#onCreateIncomingConference}) before starting the incoming
-     * call UI.
+     * call (See
+     * {@link ConnectionService#onCreateIncomingConference(PhoneAccountHandle, ConnectionRequest)})
+     * before starting the incoming call UI.
      * <p>
      * For a managed {@link ConnectionService}, a {@link SecurityException} will be thrown if either
      * the {@link PhoneAccountHandle} does not correspond to a registered {@link PhoneAccount} or
@@ -1873,7 +1876,6 @@
      *            {@link #registerPhoneAccount}.
      * @param extras A bundle that will be passed through to
      *            {@link ConnectionService#onCreateIncomingConference}.
-     * @hide
      */
     public void addNewIncomingConference(@NonNull PhoneAccountHandle phoneAccount,
             @NonNull Bundle extras) {
@@ -2093,8 +2095,8 @@
 
 
     /**
-     * Place a new conference call with the provided participants using the system telecom service
-     * This method doesn't support placing of emergency calls.
+     * Place a new adhoc conference call with the provided participants using the system telecom
+     * service. This method doesn't support placing of emergency calls.
      *
      * An adhoc conference call is established by providing a list of addresses to
      * {@code TelecomManager#startConference(List<Uri>, int videoState)} where the
@@ -2112,7 +2114,6 @@
      *
      * @param participants List of participants to start conference with
      * @param extras Bundle of extras to use with the call
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.CALL_PHONE)
     public void startConference(@NonNull List<Uri> participants,
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 0965249..19cb7f4 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -322,6 +322,8 @@
      */
     void handleCallIntent(in Intent intent, in String callingPackageProxy);
 
+    void cleanupStuckCalls();
+
     void setTestDefaultCallRedirectionApp(String packageName);
 
     void setTestPhoneAcctSuggestionComponent(String flattenedComponentName);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7c96f05..3315e8d 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -773,7 +773,7 @@
      * {@link #KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL}). If false, this device will fallback to
      * circuit switch for supplementary services and will disable this capability for IMS entirely.
      *
-     * The default value for this key is {@code true}.
+     * The default value for this key is {@code false}.
      */
     public static final String KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL =
             "carrier_supports_ss_over_ut_bool";
@@ -1157,15 +1157,14 @@
     /**
      * Determines whether adhoc conference calls are supported by a carrier.  When {@code true},
      * adhoc conference calling is supported, {@code false otherwise}.
-     * @hide
      */
     public static final String KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL =
             "support_adhoc_conference_calls_bool";
 
     /**
-     * Determines whether conference participants can be added to existing call.  When {@code true},
+     * Determines whether conference participants can be added to existing call to form an adhoc
+     * conference call (in contrast to merging calls to form a conference).  When {@code true},
      * adding conference participants to existing call is supported, {@code false otherwise}.
-     * @hide
      */
     public static final String KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL =
             "support_add_conference_participants_bool";
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index 61f68ce..427721f4 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -34,10 +34,12 @@
 public abstract class CellLocation {
 
     /**
-     * This method will not do anything.
+     * Request an updated CellLocation for callers targeting SDK 30 or older.
      *
-     * Whenever location changes, a callback will automatically be be sent to
-     * all registrants of {@link PhoneStateListener#LISTEN_CELL_LOCATION}.
+     * Whenever Android is aware of location changes, a callback will automatically be sent to
+     * all registrants of {@link PhoneStateListener#LISTEN_CELL_LOCATION}. This API requests an
+     * additional location update for cases where power saving might cause location updates to be
+     * missed.
      *
      * <p>This method is a no-op for callers targeting SDK level 31 or greater.
      * <p>This method is a no-op for callers that target SDK level 29 or 30 and lack
@@ -45,14 +47,7 @@
      * <p>This method is a no-op for callers that target SDK level 28 or below and lack
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
      *
-     * Callers wishing to request a single location update should use
-     * {@link TelephonyManager#requestCellInfoUpdate}.
-     *
-     * @deprecated this method has undesirable side-effects, and it calls into the OS without
-     * access to a {@link android.content.Context Context}, meaning that certain safety checks and
-     * attribution are error-prone. Given that this method has numerous downsides, and given that
-     * there are long-available superior alternatives, callers are strongly discouraged from using
-     * this method.
+     * @deprecated use {@link TelephonyManager#requestCellInfoUpdate}.
      */
     @Deprecated
     public static void requestLocationUpdate() {
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 8e50bba..766019e 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -149,7 +149,7 @@
         mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
         mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
         mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
-        mSsRsrq = inRangeOrUnavailable(ssRsrq, -20, -3);
+        mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
         mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
         updateLevel(null, null);
     }
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index abcc82b..1dbec2c 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -1656,8 +1656,7 @@
      * operation is performed on the correct subscription.
      * </p>
      *
-     * @param messageIndex This is the same index used to access a message
-     * from {@link #getMessagesFromIcc()}.
+     * @param messageIndex the message index of the message in the ICC (1-based index).
      * @return true for success, false if the operation fails. Failure can be due to IPC failure,
      * RIL/modem error which results in SMS failed to be deleted on SIM
      *
@@ -1740,7 +1739,7 @@
      * operation is performed on the correct subscription.
      * </p>
      *
-     * @return <code>List</code> of <code>SmsMessage</code> objects
+     * @return <code>List</code> of <code>SmsMessage</code> objects for valid records only.
      *
      * {@hide}
      */
diff --git a/tests/LocalizationTest/Android.bp b/tests/LocalizationTest/Android.bp
new file mode 100644
index 0000000..c4bfcb1
--- /dev/null
+++ b/tests/LocalizationTest/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+    name: "LocalizationTest",
+    srcs: ["java/**/*.kt"],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.test.mock",
+    ],
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "mockito-target-extended-minus-junit4",
+        "truth-prebuilt",
+    ],
+    jni_libs: [
+        // For mockito extended
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+    certificate: "platform",
+    platform_apis: true,
+    test_suites: ["device-tests"],
+    optimize: {
+        enabled: false,
+    },
+}
diff --git a/tests/LocalizationTest/AndroidManifest.xml b/tests/LocalizationTest/AndroidManifest.xml
new file mode 100644
index 0000000..b135443
--- /dev/null
+++ b/tests/LocalizationTest/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.android.internal.app">
+
+    <application android:debuggable="true"  android:testOnly="true">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.android.internal.app"
+        android:label="Localization Tests" />
+
+</manifest>
diff --git a/tests/LocalizationTest/AndroidTest.xml b/tests/LocalizationTest/AndroidTest.xml
new file mode 100644
index 0000000..8309b4f
--- /dev/null
+++ b/tests/LocalizationTest/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<configuration description="Localization Tests.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-instrumentation" />
+
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="install-arg" value="-t" />
+        <option name="test-file-name" value="LocalizationTest.apk" />
+    </target_preparer>
+
+    <option name="test-tag" value="LocalizationTest" />
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.android.internal.app" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/LocalizationTest/java/com/android/internal/app/LocalizationTest.kt b/tests/LocalizationTest/java/com/android/internal/app/LocalizationTest.kt
new file mode 100644
index 0000000..22ea971
--- /dev/null
+++ b/tests/LocalizationTest/java/com/android/internal/app/LocalizationTest.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.android.internal.app
+
+import android.os.SystemProperties
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
+import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
+import com.android.internal.R
+import com.android.internal.app.LocalePicker
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.After
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.MockitoSession
+
+@RunWith(AndroidJUnit4::class)
+class LocalizationTest {
+    private val mContext = InstrumentationRegistry.getInstrumentation().context
+    private val mUnfilteredLocales =
+            mContext.getResources().getStringArray(R.array.supported_locales)
+
+    private lateinit var mMockitoSession: MockitoSession
+
+    @Before
+    fun setUp() {
+        mMockitoSession = mockitoSession()
+                .initMocks(this)
+                .spyStatic(SystemProperties::class.java)
+                .startMocking()
+    }
+
+    @After
+    fun tearDown() {
+        mMockitoSession.finishMocking()
+    }
+
+    @Test
+    fun testGetSupportedLocales_noFilter() {
+        // Filter not set.
+        setTestLocaleFilter(null)
+
+        val locales1 = LocalePicker.getSupportedLocales(mContext)
+
+        assertThat(locales1).isEqualTo(mUnfilteredLocales)
+
+        // Empty filter.
+        setTestLocaleFilter("")
+
+        val locales2 = LocalePicker.getSupportedLocales(mContext)
+
+        assertThat(locales2).isEqualTo(mUnfilteredLocales)
+    }
+
+    @Test
+    fun testGetSupportedLocales_invalidFilter() {
+        setTestLocaleFilter("**")
+
+        val locales = LocalePicker.getSupportedLocales(mContext)
+
+        assertThat(locales).isEqualTo(mUnfilteredLocales)
+    }
+
+    @Test
+    fun testGetSupportedLocales_inclusiveFilter() {
+        setTestLocaleFilter("^(de-AT|de-DE|en|ru).*")
+
+        val locales = LocalePicker.getSupportedLocales(mContext)
+
+        assertThat(locales).isEqualTo(
+                mUnfilteredLocales
+                        .filter { it.startsWithAnyOf("de-AT", "de-DE", "en", "ru") }
+                        .toTypedArray()
+        )
+    }
+
+    @Test
+    fun testGetSupportedLocales_exclusiveFilter() {
+        setTestLocaleFilter("^(?!de-IT|es|fr).*")
+
+        val locales = LocalePicker.getSupportedLocales(mContext)
+
+        assertThat(locales).isEqualTo(
+                mUnfilteredLocales
+                        .filter { !it.startsWithAnyOf("de-IT", "es", "fr") }
+                        .toTypedArray()
+        )
+    }
+
+    private fun setTestLocaleFilter(localeFilter: String?) {
+        doReturn(localeFilter).`when` { SystemProperties.get(eq("ro.localization.locale_filter")) }
+    }
+
+    private fun String.startsWithAnyOf(vararg prefixes: String): Boolean {
+        prefixes.forEach {
+            if (startsWith(it)) return true
+        }
+
+        return false
+    }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index bc85374..e6346ea 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -4226,7 +4226,7 @@
             callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
         }
 
-        // Sanity check before testing started keepalive.
+        // Basic check before testing started keepalive.
         try (SocketKeepalive ka = mCm.createSocketKeepalive(
                 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
             ka.start(validKaInterval);
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index fdc6084..6633c9d 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -26,8 +26,6 @@
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
-import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
-import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_REQUIRED;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.MATCH_ANY_USER;
 import static android.os.Process.SYSTEM_UID;
@@ -97,7 +95,6 @@
     private static final int SYSTEM_UID1 = 1000;
     private static final int SYSTEM_UID2 = 1008;
     private static final int VPN_UID = 10002;
-    private static final String REAL_SYSTEM_PACKAGE_NAME = "android";
     private static final String MOCK_PACKAGE1 = "appName1";
     private static final String MOCK_PACKAGE2 = "appName2";
     private static final String SYSTEM_PACKAGE1 = "sysName1";
@@ -128,6 +125,7 @@
                         new UserInfo(MOCK_USER1, "", 0),
                         new UserInfo(MOCK_USER2, "", 0),
                 }));
+        doReturn(PackageManager.PERMISSION_DENIED).when(mDeps).uidPermission(anyString(), anyInt());
 
         mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
 
@@ -140,35 +138,22 @@
         verify(mMockPmi).getPackageList(mPermissionMonitor);
     }
 
+    /**
+     * Remove all permissions from the uid then build new package info and setup permissions to uid
+     * for checking restricted network permission.
+     */
     private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
             String... permissions) {
-        final PackageInfo packageInfo =
-                packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, permissions, partition);
+        final PackageInfo packageInfo = buildPackageInfo(partition, uid, MOCK_USER1);
         packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
-        packageInfo.applicationInfo.uid = uid;
-        return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo);
+        removeAllPermissions(uid);
+        addPermissions(uid, permissions);
+        return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo.applicationInfo);
     }
 
-    private static PackageInfo systemPackageInfoWithPermissions(String... permissions) {
-        return packageInfoWithPermissions(
-                REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
-    }
-
-    private static PackageInfo vendorPackageInfoWithPermissions(String... permissions) {
-        return packageInfoWithPermissions(
-                REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_VENDOR);
-    }
-
-    private static PackageInfo packageInfoWithPermissions(int permissionsFlags,
-            String[] permissions, String partition) {
-        int[] requestedPermissionsFlags = new int[permissions.length];
-        for (int i = 0; i < permissions.length; i++) {
-            requestedPermissionsFlags[i] = permissionsFlags;
-        }
+    private static PackageInfo packageInfoWithPartition(String partition) {
         final PackageInfo packageInfo = new PackageInfo();
-        packageInfo.requestedPermissions = permissions;
         packageInfo.applicationInfo = new ApplicationInfo();
-        packageInfo.requestedPermissionsFlags = requestedPermissionsFlags;
         int privateFlags = 0;
         switch (partition) {
             case PARTITION_OEM:
@@ -185,85 +170,65 @@
         return packageInfo;
     }
 
-    private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid, int userId) {
-        final PackageInfo pkgInfo;
-        if (hasSystemPermission) {
-            pkgInfo = systemPackageInfoWithPermissions(
-                    CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
-        } else {
-            pkgInfo = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, new String[] {}, "");
-        }
+    private static PackageInfo buildPackageInfo(String partition, int uid, int userId) {
+        final PackageInfo pkgInfo = packageInfoWithPartition(partition);
         pkgInfo.applicationInfo.uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
         return pkgInfo;
     }
 
+    /** This will REMOVE all previously set permissions from given uid. */
+    private void removeAllPermissions(int uid) {
+        doReturn(PackageManager.PERMISSION_DENIED).when(mDeps).uidPermission(anyString(), eq(uid));
+    }
+
+    /** Set up mocks so that given UID has the requested permissions. */
+    private void addPermissions(int uid, String... permissions) {
+        for (String permission : permissions) {
+            doReturn(PackageManager.PERMISSION_GRANTED)
+                    .when(mDeps).uidPermission(eq(permission), eq(uid));
+        }
+    }
+
     @Test
     public void testHasPermission() {
-        PackageInfo app = systemPackageInfoWithPermissions();
-        assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
-        assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
-        assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
-        assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
+        addPermissions(MOCK_UID1);
+        assertFalse(mPermissionMonitor.hasPermission(CHANGE_NETWORK_STATE, MOCK_UID1));
+        assertFalse(mPermissionMonitor.hasPermission(NETWORK_STACK, MOCK_UID1));
+        assertFalse(mPermissionMonitor.hasPermission(
+                CONNECTIVITY_USE_RESTRICTED_NETWORKS, MOCK_UID1));
+        assertFalse(mPermissionMonitor.hasPermission(CONNECTIVITY_INTERNAL, MOCK_UID1));
 
-        app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE, NETWORK_STACK);
-        assertTrue(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
-        assertTrue(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
-        assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
-        assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
+        addPermissions(MOCK_UID1, CHANGE_NETWORK_STATE, NETWORK_STACK);
+        assertTrue(mPermissionMonitor.hasPermission(CHANGE_NETWORK_STATE, MOCK_UID1));
+        assertTrue(mPermissionMonitor.hasPermission(NETWORK_STACK, MOCK_UID1));
+        assertFalse(mPermissionMonitor.hasPermission(
+                CONNECTIVITY_USE_RESTRICTED_NETWORKS, MOCK_UID1));
+        assertFalse(mPermissionMonitor.hasPermission(CONNECTIVITY_INTERNAL, MOCK_UID1));
+        assertFalse(mPermissionMonitor.hasPermission(CHANGE_NETWORK_STATE, MOCK_UID2));
+        assertFalse(mPermissionMonitor.hasPermission(NETWORK_STACK, MOCK_UID2));
 
-        app = systemPackageInfoWithPermissions(
-                CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL);
-        assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
-        assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
-        assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
-        assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
-
-        app = packageInfoWithPermissions(REQUESTED_PERMISSION_REQUIRED, new String[] {
-                CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL, NETWORK_STACK },
-                PARTITION_SYSTEM);
-        assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
-        assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
-        assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
-        assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
-
-        app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
-        app.requestedPermissions = null;
-        assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
-
-        app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
-        app.requestedPermissionsFlags = null;
-        assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
+        addPermissions(MOCK_UID2, CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL);
+        assertFalse(mPermissionMonitor.hasPermission(
+                CONNECTIVITY_USE_RESTRICTED_NETWORKS, MOCK_UID1));
+        assertFalse(mPermissionMonitor.hasPermission(CONNECTIVITY_INTERNAL, MOCK_UID1));
+        assertTrue(mPermissionMonitor.hasPermission(
+                CONNECTIVITY_USE_RESTRICTED_NETWORKS, MOCK_UID2));
+        assertTrue(mPermissionMonitor.hasPermission(CONNECTIVITY_INTERNAL, MOCK_UID2));
     }
 
     @Test
     public void testIsVendorApp() {
-        PackageInfo app = systemPackageInfoWithPermissions();
+        PackageInfo app = packageInfoWithPartition(PARTITION_SYSTEM);
         assertFalse(mPermissionMonitor.isVendorApp(app.applicationInfo));
-        app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
-                new String[] {}, PARTITION_OEM);
+        app = packageInfoWithPartition(PARTITION_OEM);
         assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
-        app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
-                new String[] {}, PARTITION_PRODUCT);
+        app = packageInfoWithPartition(PARTITION_PRODUCT);
         assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
-        app = vendorPackageInfoWithPermissions();
+        app = packageInfoWithPartition(PARTITION_VENDOR);
         assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
     }
 
     @Test
-    public void testHasNetworkPermission() {
-        PackageInfo app = systemPackageInfoWithPermissions();
-        assertFalse(mPermissionMonitor.hasNetworkPermission(app));
-        app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
-        assertTrue(mPermissionMonitor.hasNetworkPermission(app));
-        app = systemPackageInfoWithPermissions(NETWORK_STACK);
-        assertFalse(mPermissionMonitor.hasNetworkPermission(app));
-        app = systemPackageInfoWithPermissions(CONNECTIVITY_USE_RESTRICTED_NETWORKS);
-        assertFalse(mPermissionMonitor.hasNetworkPermission(app));
-        app = systemPackageInfoWithPermissions(CONNECTIVITY_INTERNAL);
-        assertFalse(mPermissionMonitor.hasNetworkPermission(app));
-    }
-
-    @Test
     public void testHasRestrictedNetworkPermission() {
         assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
         assertFalse(hasRestrictedNetworkPermission(
@@ -323,30 +288,27 @@
     private void assertBackgroundPermission(boolean hasPermission, String name, int uid,
             String... permissions) throws Exception {
         when(mPackageManager.getPackageInfo(eq(name), anyInt()))
-                .thenReturn(packageInfoWithPermissions(
-                        REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM));
+                .thenReturn(buildPackageInfo(PARTITION_SYSTEM, uid, MOCK_USER1));
+        addPermissions(uid, permissions);
         mPermissionMonitor.onPackageAdded(name, uid);
         assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid));
     }
 
     @Test
     public void testHasUseBackgroundNetworksPermission() throws Exception {
+        doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
         assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
-        assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID);
-        assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID, CONNECTIVITY_INTERNAL);
-        assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_NETWORK_STATE);
-        assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, NETWORK_STACK);
+        assertBackgroundPermission(false, "system1", SYSTEM_UID);
+        assertBackgroundPermission(false, "system2", SYSTEM_UID, CONNECTIVITY_INTERNAL);
+        assertBackgroundPermission(true, "system3", SYSTEM_UID, CHANGE_NETWORK_STATE);
 
         assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1));
-        assertBackgroundPermission(false, MOCK_PACKAGE1, MOCK_UID1);
-        assertBackgroundPermission(true, MOCK_PACKAGE1, MOCK_UID1,
-                CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+        assertBackgroundPermission(false, "mock1", MOCK_UID1);
+        assertBackgroundPermission(true, "mock2", MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
 
         assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2));
-        assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2);
-        assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2,
-                CONNECTIVITY_INTERNAL);
-        assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID2, NETWORK_STACK);
+        assertBackgroundPermission(false, "mock3", MOCK_UID2, CONNECTIVITY_INTERNAL);
+        assertBackgroundPermission(true, "mock4", MOCK_UID2, NETWORK_STACK);
     }
 
     private class NetdMonitor {
@@ -416,13 +378,14 @@
         // MOCK_UID1: MOCK_PACKAGE1 only has network permission.
         // SYSTEM_UID: SYSTEM_PACKAGE1 has system permission.
         // SYSTEM_UID: SYSTEM_PACKAGE2 only has network permission.
-        doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(eq(SYSTEM), anyString());
+        doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(eq(SYSTEM),
+                anyString(), anyInt());
         doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(any(),
-                eq(SYSTEM_PACKAGE1));
+                eq(SYSTEM_PACKAGE1), anyInt());
         doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
-                eq(SYSTEM_PACKAGE2));
+                eq(SYSTEM_PACKAGE2), anyInt());
         doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
-                eq(MOCK_PACKAGE1));
+                eq(MOCK_PACKAGE1), anyInt());
 
         // Add SYSTEM_PACKAGE2, expect only have network permission.
         mPermissionMonitor.onUserAdded(MOCK_USER1);
@@ -473,13 +436,15 @@
     public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception {
         when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
                 Arrays.asList(new PackageInfo[] {
-                        buildPackageInfo(/* SYSTEM */ true, SYSTEM_UID1, MOCK_USER1),
-                        buildPackageInfo(/* SYSTEM */ false, MOCK_UID1, MOCK_USER1),
-                        buildPackageInfo(/* SYSTEM */ false, MOCK_UID2, MOCK_USER1),
-                        buildPackageInfo(/* SYSTEM */ false, VPN_UID, MOCK_USER1)
+                        buildPackageInfo(PARTITION_SYSTEM, SYSTEM_UID1, MOCK_USER1),
+                        buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1),
+                        buildPackageInfo(PARTITION_SYSTEM, MOCK_UID2, MOCK_USER1),
+                        buildPackageInfo(PARTITION_SYSTEM, VPN_UID, MOCK_USER1)
                 }));
         when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
-                buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
+                buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1));
+        addPermissions(SYSTEM_UID,
+                CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
         mPermissionMonitor.startMonitoring();
         // Every app on user 0 except MOCK_UID2 are under VPN.
         final Set<UidRange> vpnRange1 = new HashSet<>(Arrays.asList(new UidRange[] {
@@ -524,11 +489,11 @@
     public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception {
         when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
                 Arrays.asList(new PackageInfo[] {
-                        buildPackageInfo(true, SYSTEM_UID1, MOCK_USER1),
-                        buildPackageInfo(false, VPN_UID, MOCK_USER1)
+                        buildPackageInfo(PARTITION_SYSTEM, SYSTEM_UID1, MOCK_USER1),
+                        buildPackageInfo(PARTITION_SYSTEM, VPN_UID, MOCK_USER1)
                 }));
         when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
-                        buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
+                        buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1));
 
         mPermissionMonitor.startMonitoring();
         final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(MOCK_USER1));
@@ -633,10 +598,10 @@
 
     private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions)
             throws Exception {
-        PackageInfo packageInfo = packageInfoWithPermissions(
-                REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
+        final PackageInfo packageInfo = buildPackageInfo(PARTITION_SYSTEM, uid, MOCK_USER1);
         when(mPackageManager.getPackageInfo(eq(packageName), anyInt())).thenReturn(packageInfo);
         when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[]{packageName});
+        addPermissions(uid, permissions);
         return packageInfo;
     }
 
@@ -663,14 +628,13 @@
     public void testPackageInstallSharedUid() throws Exception {
         final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
 
-        PackageInfo packageInfo1 = addPackage(MOCK_PACKAGE1, MOCK_UID1,
-                new String[] {INTERNET, UPDATE_DEVICE_STATS});
+        addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
         mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
                 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
 
         // Install another package with the same uid and no permissions should not cause the UID to
         // lose permissions.
-        PackageInfo packageInfo2 = systemPackageInfoWithPermissions();
+        final PackageInfo packageInfo2 = buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1);
         when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
         when(mPackageManager.getPackagesForUid(MOCK_UID1))
               .thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
@@ -701,6 +665,7 @@
                 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
 
         when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
+        removeAllPermissions(MOCK_UID1);
         mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
         mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
 
@@ -728,10 +693,12 @@
                 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
 
         // Mock another package with the same uid but different permissions.
-        PackageInfo packageInfo2 = systemPackageInfoWithPermissions(INTERNET);
+        final PackageInfo packageInfo2 = buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1);
         when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
         when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{
                 MOCK_PACKAGE2});
+        removeAllPermissions(MOCK_UID1);
+        addPermissions(MOCK_UID1, INTERNET);
 
         mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
         mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
@@ -743,9 +710,6 @@
         // necessary permission.
         final Context realContext = InstrumentationRegistry.getContext();
         final PermissionMonitor monitor = new PermissionMonitor(realContext, mNetdService);
-        final PackageManager manager = realContext.getPackageManager();
-        final PackageInfo systemInfo = manager.getPackageInfo(REAL_SYSTEM_PACKAGE_NAME,
-                GET_PERMISSIONS | MATCH_ANY_USER);
-        assertTrue(monitor.hasPermission(systemInfo, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
+        assertTrue(monitor.hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, SYSTEM_UID));
     }
 }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index 551498f..e83d2a9 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -23,11 +23,12 @@
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkStatsHistory.FIELD_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
+import static android.net.NetworkUtils.multiplySafeByRational;
 import static android.os.Process.myUid;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 
-import static com.android.server.net.NetworkStatsCollection.multiplySafe;
+import static com.android.testutils.MiscAssertsKt.assertThrows;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -505,23 +506,25 @@
     }
 
     @Test
-    public void testMultiplySafe() {
-        assertEquals(25, multiplySafe(50, 1, 2));
-        assertEquals(100, multiplySafe(50, 2, 1));
+    public void testMultiplySafeRational() {
+        assertEquals(25, multiplySafeByRational(50, 1, 2));
+        assertEquals(100, multiplySafeByRational(50, 2, 1));
 
-        assertEquals(-10, multiplySafe(30, -1, 3));
-        assertEquals(0, multiplySafe(30, 0, 3));
-        assertEquals(10, multiplySafe(30, 1, 3));
-        assertEquals(20, multiplySafe(30, 2, 3));
-        assertEquals(30, multiplySafe(30, 3, 3));
-        assertEquals(40, multiplySafe(30, 4, 3));
+        assertEquals(-10, multiplySafeByRational(30, -1, 3));
+        assertEquals(0, multiplySafeByRational(30, 0, 3));
+        assertEquals(10, multiplySafeByRational(30, 1, 3));
+        assertEquals(20, multiplySafeByRational(30, 2, 3));
+        assertEquals(30, multiplySafeByRational(30, 3, 3));
+        assertEquals(40, multiplySafeByRational(30, 4, 3));
 
         assertEquals(100_000_000_000L,
-                multiplySafe(300_000_000_000L, 10_000_000_000L, 30_000_000_000L));
+                multiplySafeByRational(300_000_000_000L, 10_000_000_000L, 30_000_000_000L));
         assertEquals(100_000_000_010L,
-                multiplySafe(300_000_000_000L, 10_000_000_001L, 30_000_000_000L));
+                multiplySafeByRational(300_000_000_000L, 10_000_000_001L, 30_000_000_000L));
         assertEquals(823_202_048L,
-                multiplySafe(4_939_212_288L, 2_121_815_528L, 12_730_893_165L));
+                multiplySafeByRational(4_939_212_288L, 2_121_815_528L, 12_730_893_165L));
+
+        assertThrows(ArithmeticException.class, () -> multiplySafeByRational(30, 3, 0));
     }
 
     /**