Merge "Fix parcelling of Kernel Wakelock/reason"
diff --git a/Android.bp b/Android.bp
index 80f1c37..114ca2c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,6 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Build ext.jar
+// ============================================================
+java_library {
+    name: "ext",
+    no_framework_libs: true,
+    static_libs: [
+        "libphonenumber-platform",
+        "nist-sip",
+        "tagsoup",
+    ],
+    dxflags: ["--core-library"],
+}
+
 // ====  c++ proto device library  ==============================
 cc_library {
     name: "libplatformprotos",
diff --git a/Android.mk b/Android.mk
index 98e4299..4a57020 100644
--- a/Android.mk
+++ b/Android.mk
@@ -548,9 +548,10 @@
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
 	telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
-	wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl \
-	wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl \
 	wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl \
+	wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl \
+	wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl \
+	wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl \
 	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
 	wifi/java/android/net/wifi/rtt/IRttCallback.aidl \
 	wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl \
@@ -1030,6 +1031,7 @@
     -since $(SRC_API_DIR)/24.txt 24 \
     -since $(SRC_API_DIR)/25.txt 25 \
     -since $(SRC_API_DIR)/26.txt 26 \
+    -since $(SRC_API_DIR)/27.txt 27 \
     -werror -lerror -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128 \
     -overview $(LOCAL_PATH)/core/java/overview.html \
 
@@ -1525,35 +1527,6 @@
 
 include $(BUILD_DROIDDOC)
 
-# Build ext.jar
-# ============================================================
-
-ext_dirs := \
-	../../external/nist-sip/java \
-	../../external/tagsoup/src \
-
-ext_src_files := $(call all-java-files-under,$(ext_dirs))
-
-# ====  the library  =========================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(ext_src_files)
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
-LOCAL_STATIC_JAVA_LIBRARIES := libphonenumber-platform
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := ext
-
-LOCAL_DX_FLAGS := --core-library
-
-ifneq ($(INCREMENTAL_BUILDS),)
-    LOCAL_PROGUARD_ENABLED := disabled
-    LOCAL_JACK_ENABLED := incremental
-endif
-
-include $(BUILD_JAVA_LIBRARY)
-
 # ====  java proto host library  ==============================
 include $(CLEAR_VARS)
 LOCAL_MODULE := platformprotos
diff --git a/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java b/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java
index 47dd257..586c385 100644
--- a/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java
@@ -46,7 +46,7 @@
     private static final float SPACING_ADD = 10f;
     private static final float SPACING_MULT = 1.5f;
 
-    @Parameterized.Parameters(name = "cached={3},{1} chars,{0}")
+    @Parameterized.Parameters(name = "cached={3},{1}chars,{0}")
     public static Collection cases() {
         final List<Object[]> params = new ArrayList<>();
         for (int length : new int[]{128}) {
diff --git a/apct-tests/perftests/core/src/android/text/BoringLayoutIsBoringPerfTest.java b/apct-tests/perftests/core/src/android/text/BoringLayoutIsBoringPerfTest.java
index 34de65d..9d11f29 100644
--- a/apct-tests/perftests/core/src/android/text/BoringLayoutIsBoringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/BoringLayoutIsBoringPerfTest.java
@@ -40,7 +40,7 @@
 
     private static final boolean[] BOOLEANS = new boolean[]{false, true};
 
-    @Parameterized.Parameters(name = "cached={4},{1} chars,{0}")
+    @Parameterized.Parameters(name = "cached={4},{1}chars,{0}")
     public static Collection cases() {
         final List<Object[]> params = new ArrayList<>();
         for (int length : new int[]{128}) {
diff --git a/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java b/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java
index 00b60ad..6768798 100644
--- a/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java
@@ -42,7 +42,7 @@
 
     private static final boolean[] BOOLEANS = new boolean[]{false, true};
 
-    @Parameterized.Parameters(name = "cached={1},{0} chars")
+    @Parameterized.Parameters(name = "cached={1},{0}chars")
     public static Collection cases() {
         final List<Object[]> params = new ArrayList<>();
         for (int length : new int[]{128}) {
diff --git a/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java b/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java
index 356e2e0..bfdb758 100644
--- a/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java
@@ -50,7 +50,7 @@
     @Rule
     public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
 
-    @Parameterized.Parameters(name = "cached={3},{1} chars,{0}")
+    @Parameterized.Parameters(name = "cached={3},{1}chars,{0}")
     public static Collection cases() {
         final List<Object[]> params = new ArrayList<>();
         for (int length : new int[]{128}) {
diff --git a/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java b/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java
index a2bf33e1..ff2d57e 100644
--- a/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java
@@ -40,7 +40,7 @@
 import java.util.Random;
 
 /**
- * Performance test for multi line, single style {@link StaticLayout} creation/draw.
+ * Performance test for {@link TextView} measure/draw.
  */
 @LargeTest
 @RunWith(Parameterized.class)
@@ -51,7 +51,7 @@
     @Rule
     public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
 
-    @Parameterized.Parameters(name = "cached={3},{1} chars,{0}")
+    @Parameterized.Parameters(name = "cached={3},{1}chars,{0}")
     public static Collection cases() {
         final List<Object[]> params = new ArrayList<>();
         for (int length : new int[]{128}) {
diff --git a/api/current.txt b/api/current.txt
index f133562..79816ac 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -362,6 +362,7 @@
     field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
     field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
     field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
+    field public static final int cantSaveState = 16844142; // 0x101056e
     field public static final deprecated int capitalize = 16843113; // 0x1010169
     field public static final int category = 16843752; // 0x10103e8
     field public static final int centerBright = 16842956; // 0x10100cc
@@ -4022,6 +4023,7 @@
   public class ActivityOptions {
     method public android.graphics.Rect getLaunchBounds();
     method public int getLaunchDisplayId();
+    method public boolean getLockTaskMode();
     method public static android.app.ActivityOptions makeBasic();
     method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -4034,6 +4036,7 @@
     method public android.app.ActivityOptions setAppVerificationBundle(android.os.Bundle);
     method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
     method public android.app.ActivityOptions setLaunchDisplayId(int);
+    method public android.app.ActivityOptions setLockTaskMode(boolean);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
     field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
@@ -5643,8 +5646,10 @@
     method public static java.lang.String suppressedEffectsToString(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.NotificationManager.Policy> CREATOR;
+    field public static final int PRIORITY_CATEGORY_ALARMS = 32; // 0x20
     field public static final int PRIORITY_CATEGORY_CALLS = 8; // 0x8
     field public static final int PRIORITY_CATEGORY_EVENTS = 2; // 0x2
+    field public static final int PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER = 64; // 0x40
     field public static final int PRIORITY_CATEGORY_MESSAGES = 4; // 0x4
     field public static final int PRIORITY_CATEGORY_REMINDERS = 1; // 0x1
     field public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 16; // 0x10
@@ -6669,6 +6674,9 @@
     method public int getInputType();
     method public int getLeft();
     method public android.os.LocaleList getLocaleList();
+    method public int getMaxTextEms();
+    method public int getMaxTextLength();
+    method public int getMinTextEms();
     method public int getScrollX();
     method public int getScrollY();
     method public java.lang.CharSequence getText();
@@ -10999,6 +11007,7 @@
     method public android.content.ComponentName getActivity();
     method public java.util.Set<java.lang.String> getCategories();
     method public java.lang.CharSequence getDisabledMessage();
+    method public int getDisabledReason();
     method public android.os.PersistableBundle getExtras();
     method public java.lang.String getId();
     method public android.content.Intent getIntent();
@@ -11017,6 +11026,13 @@
     method public boolean isPinned();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.pm.ShortcutInfo> CREATOR;
+    field public static final int DISABLED_REASON_APP_CHANGED = 2; // 0x2
+    field public static final int DISABLED_REASON_BACKUP_NOT_SUPPORTED = 101; // 0x65
+    field public static final int DISABLED_REASON_BY_APP = 1; // 0x1
+    field public static final int DISABLED_REASON_NOT_DISABLED = 0; // 0x0
+    field public static final int DISABLED_REASON_OTHER_RESTORE_ISSUE = 103; // 0x67
+    field public static final int DISABLED_REASON_SIGNATURE_MISMATCH = 102; // 0x66
+    field public static final int DISABLED_REASON_VERSION_LOWER = 100; // 0x64
     field public static final java.lang.String SHORTCUT_CATEGORY_CONVERSATION = "android.shortcut.conversation";
   }
 
@@ -31834,6 +31850,7 @@
     field public static final java.lang.String DISALLOW_SET_WALLPAPER = "no_set_wallpaper";
     field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
     field public static final java.lang.String DISALLOW_SMS = "no_sms";
+    field public static final java.lang.String DISALLOW_SYSTEM_ERROR_DIALOGS = "no_system_error_dialogs";
     field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
     field public static final java.lang.String DISALLOW_UNMUTE_MICROPHONE = "no_unmute_microphone";
     field public static final java.lang.String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";
@@ -37239,6 +37256,7 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
+    field public static final int FLAG_DONT_SAVE_ON_FINISH = 2; // 0x2
     field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1
     field public static final int NEGATIVE_BUTTON_STYLE_CANCEL = 0; // 0x0
     field public static final int NEGATIVE_BUTTON_STYLE_REJECT = 1; // 0x1
@@ -37260,6 +37278,7 @@
     method public android.service.autofill.SaveInfo.Builder setFlags(int);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(int, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
+    method public android.service.autofill.SaveInfo.Builder setTriggerId(android.view.autofill.AutofillId);
     method public android.service.autofill.SaveInfo.Builder setValidator(android.service.autofill.Validator);
   }
 
@@ -40033,8 +40052,12 @@
     field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT";
     field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
     field public static final int RESULT_CANCELLED = 2; // 0x2
+    field public static final int RESULT_DOWNLOAD_FAILURE = 6; // 0x6
     field public static final int RESULT_EXPIRED = 3; // 0x3
+    field public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; // 0x8
     field public static final int RESULT_IO_ERROR = 4; // 0x4
+    field public static final int RESULT_OUT_OF_STORAGE = 7; // 0x7
+    field public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; // 0x5
     field public static final int RESULT_SUCCESSFUL = 1; // 0x1
     field public static final int STATUS_ACTIVELY_DOWNLOADING = 1; // 0x1
     field public static final int STATUS_PENDING_DOWNLOAD = 2; // 0x2
@@ -40701,11 +40724,10 @@
   }
 
   public static class DownloadRequest.Builder {
-    ctor public DownloadRequest.Builder();
+    ctor public DownloadRequest.Builder(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest build();
     method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
-    method public android.telephony.mbms.DownloadRequest.Builder setSource(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
   }
 
@@ -45745,8 +45767,8 @@
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
     method public void bringToFront();
-    method public void buildDrawingCache();
-    method public void buildDrawingCache(boolean);
+    method public deprecated void buildDrawingCache();
+    method public deprecated void buildDrawingCache(boolean);
     method public void buildLayer();
     method public boolean callOnClick();
     method public boolean canResolveLayoutDirection();
@@ -45771,7 +45793,7 @@
     method protected int computeVerticalScrollRange();
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo();
     method public void createContextMenu(android.view.ContextMenu);
-    method public void destroyDrawingCache();
+    method public deprecated void destroyDrawingCache();
     method public android.view.WindowInsets dispatchApplyWindowInsets(android.view.WindowInsets);
     method public boolean dispatchCapturedPointerEvent(android.view.MotionEvent);
     method public void dispatchConfigurationChanged(android.content.res.Configuration);
@@ -45852,10 +45874,10 @@
     method public static int getDefaultSize(int, int);
     method public android.view.Display getDisplay();
     method public final int[] getDrawableState();
-    method public android.graphics.Bitmap getDrawingCache();
-    method public android.graphics.Bitmap getDrawingCache(boolean);
-    method public int getDrawingCacheBackgroundColor();
-    method public int getDrawingCacheQuality();
+    method public deprecated android.graphics.Bitmap getDrawingCache();
+    method public deprecated android.graphics.Bitmap getDrawingCache(boolean);
+    method public deprecated int getDrawingCacheBackgroundColor();
+    method public deprecated int getDrawingCacheQuality();
     method public void getDrawingRect(android.graphics.Rect);
     method public long getDrawingTime();
     method public float getElevation();
@@ -45994,7 +46016,7 @@
     method public boolean isClickable();
     method public boolean isContextClickable();
     method public boolean isDirty();
-    method public boolean isDrawingCacheEnabled();
+    method public deprecated boolean isDrawingCacheEnabled();
     method public boolean isDuplicateParentStateEnabled();
     method public boolean isEnabled();
     method public final boolean isFocusable();
@@ -46165,9 +46187,9 @@
     method public void setContentDescription(java.lang.CharSequence);
     method public void setContextClickable(boolean);
     method public void setDefaultFocusHighlightEnabled(boolean);
-    method public void setDrawingCacheBackgroundColor(int);
-    method public void setDrawingCacheEnabled(boolean);
-    method public void setDrawingCacheQuality(int);
+    method public deprecated void setDrawingCacheBackgroundColor(int);
+    method public deprecated void setDrawingCacheEnabled(boolean);
+    method public deprecated void setDrawingCacheQuality(int);
     method public void setDuplicateParentStateEnabled(boolean);
     method public void setElevation(float);
     method public void setEnabled(boolean);
@@ -46318,9 +46340,9 @@
     field public static final int DRAG_FLAG_GLOBAL_URI_READ = 1; // 0x1
     field public static final int DRAG_FLAG_GLOBAL_URI_WRITE = 2; // 0x2
     field public static final int DRAG_FLAG_OPAQUE = 512; // 0x200
-    field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
-    field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
-    field public static final int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
+    field public static final deprecated int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
+    field public static final deprecated int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
+    field public static final deprecated int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
     field protected static final int[] EMPTY_STATE_SET;
     field protected static final int[] ENABLED_FOCUSED_SELECTED_STATE_SET;
     field protected static final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
@@ -46712,7 +46734,7 @@
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
     method public android.view.ViewGroupOverlay getOverlay();
-    method public int getPersistentDrawingCache();
+    method public deprecated int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
     method public final deprecated void invalidateChild(android.view.View, android.graphics.Rect);
@@ -46765,7 +46787,7 @@
     method public void setAddStatesFromChildren(boolean);
     method public deprecated void setAlwaysDrawnWithCacheEnabled(boolean);
     method public deprecated void setAnimationCacheEnabled(boolean);
-    method protected void setChildrenDrawingCacheEnabled(boolean);
+    method protected deprecated void setChildrenDrawingCacheEnabled(boolean);
     method protected void setChildrenDrawingOrderEnabled(boolean);
     method protected deprecated void setChildrenDrawnWithCacheEnabled(boolean);
     method public void setClipChildren(boolean);
@@ -46777,7 +46799,7 @@
     method public void setLayoutTransition(android.animation.LayoutTransition);
     method public void setMotionEventSplittingEnabled(boolean);
     method public void setOnHierarchyChangeListener(android.view.ViewGroup.OnHierarchyChangeListener);
-    method public void setPersistentDrawingCache(int);
+    method public deprecated void setPersistentDrawingCache(int);
     method protected void setStaticTransformationsEnabled(boolean);
     method public void setTouchscreenBlocksFocus(boolean);
     method public void setTransitionGroup(boolean);
@@ -46795,10 +46817,10 @@
     field public static final int FOCUS_BLOCK_DESCENDANTS = 393216; // 0x60000
     field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
     field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
-    field public static final int PERSISTENT_ALL_CACHES = 3; // 0x3
-    field public static final int PERSISTENT_ANIMATION_CACHE = 1; // 0x1
-    field public static final int PERSISTENT_NO_CACHE = 0; // 0x0
-    field public static final int PERSISTENT_SCROLLING_CACHE = 2; // 0x2
+    field public static final deprecated int PERSISTENT_ALL_CACHES = 3; // 0x3
+    field public static final deprecated int PERSISTENT_ANIMATION_CACHE = 1; // 0x1
+    field public static final deprecated int PERSISTENT_NO_CACHE = 0; // 0x0
+    field public static final deprecated int PERSISTENT_SCROLLING_CACHE = 2; // 0x2
   }
 
   public static class ViewGroup.LayoutParams {
@@ -46996,6 +47018,9 @@
     method public abstract void setInputType(int);
     method public abstract void setLocaleList(android.os.LocaleList);
     method public abstract void setLongClickable(boolean);
+    method public abstract void setMaxTextEms(int);
+    method public abstract void setMaxTextLength(int);
+    method public abstract void setMinTextEms(int);
     method public abstract void setOpaque(boolean);
     method public abstract void setSelected(boolean);
     method public abstract void setText(java.lang.CharSequence);
diff --git a/api/system-current.txt b/api/system-current.txt
index c1b109c..40683d3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -494,6 +494,7 @@
     field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
     field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
     field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
+    field public static final int cantSaveState = 16844142; // 0x101056e
     field public static final deprecated int capitalize = 16843113; // 0x1010169
     field public static final int category = 16843752; // 0x10103e8
     field public static final int centerBright = 16842956; // 0x10100cc
@@ -4184,6 +4185,7 @@
   public class ActivityOptions {
     method public android.graphics.Rect getLaunchBounds();
     method public int getLaunchDisplayId();
+    method public boolean getLockTaskMode();
     method public static android.app.ActivityOptions makeBasic();
     method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -4196,6 +4198,7 @@
     method public android.app.ActivityOptions setAppVerificationBundle(android.os.Bundle);
     method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
     method public android.app.ActivityOptions setLaunchDisplayId(int);
+    method public android.app.ActivityOptions setLockTaskMode(boolean);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
     field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
@@ -5851,8 +5854,10 @@
     method public static java.lang.String suppressedEffectsToString(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.NotificationManager.Policy> CREATOR;
+    field public static final int PRIORITY_CATEGORY_ALARMS = 32; // 0x20
     field public static final int PRIORITY_CATEGORY_CALLS = 8; // 0x8
     field public static final int PRIORITY_CATEGORY_EVENTS = 2; // 0x2
+    field public static final int PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER = 64; // 0x40
     field public static final int PRIORITY_CATEGORY_MESSAGES = 4; // 0x4
     field public static final int PRIORITY_CATEGORY_REMINDERS = 1; // 0x1
     field public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 16; // 0x10
@@ -6920,6 +6925,9 @@
     method public int getInputType();
     method public int getLeft();
     method public android.os.LocaleList getLocaleList();
+    method public int getMaxTextEms();
+    method public int getMaxTextLength();
+    method public int getMinTextEms();
     method public int getScrollX();
     method public int getScrollY();
     method public java.lang.CharSequence getText();
@@ -11722,6 +11730,7 @@
     method public android.content.ComponentName getActivity();
     method public java.util.Set<java.lang.String> getCategories();
     method public java.lang.CharSequence getDisabledMessage();
+    method public int getDisabledReason();
     method public android.os.PersistableBundle getExtras();
     method public java.lang.String getId();
     method public android.content.Intent getIntent();
@@ -11740,6 +11749,13 @@
     method public boolean isPinned();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.pm.ShortcutInfo> CREATOR;
+    field public static final int DISABLED_REASON_APP_CHANGED = 2; // 0x2
+    field public static final int DISABLED_REASON_BACKUP_NOT_SUPPORTED = 101; // 0x65
+    field public static final int DISABLED_REASON_BY_APP = 1; // 0x1
+    field public static final int DISABLED_REASON_NOT_DISABLED = 0; // 0x0
+    field public static final int DISABLED_REASON_OTHER_RESTORE_ISSUE = 103; // 0x67
+    field public static final int DISABLED_REASON_SIGNATURE_MISMATCH = 102; // 0x66
+    field public static final int DISABLED_REASON_VERSION_LOWER = 100; // 0x64
     field public static final java.lang.String SHORTCUT_CATEGORY_CONVERSATION = "android.shortcut.conversation";
   }
 
@@ -27217,7 +27233,6 @@
   }
 
   public static final class TvInputManager.Hardware {
-    method public boolean dispatchKeyEventToHdmi(android.view.KeyEvent);
     method public void overrideAudioSink(int, java.lang.String, int, int, int);
     method public void setStreamVolume(float);
     method public boolean setSurface(android.view.Surface, android.media.tv.TvStreamConfig);
@@ -34678,6 +34693,7 @@
     field public static final java.lang.String DISALLOW_SET_WALLPAPER = "no_set_wallpaper";
     field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
     field public static final java.lang.String DISALLOW_SMS = "no_sms";
+    field public static final java.lang.String DISALLOW_SYSTEM_ERROR_DIALOGS = "no_system_error_dialogs";
     field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
     field public static final java.lang.String DISALLOW_UNMUTE_MICROPHONE = "no_unmute_microphone";
     field public static final java.lang.String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";
@@ -40335,6 +40351,7 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
+    field public static final int FLAG_DONT_SAVE_ON_FINISH = 2; // 0x2
     field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1
     field public static final int NEGATIVE_BUTTON_STYLE_CANCEL = 0; // 0x0
     field public static final int NEGATIVE_BUTTON_STYLE_REJECT = 1; // 0x1
@@ -40356,6 +40373,7 @@
     method public android.service.autofill.SaveInfo.Builder setFlags(int);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(int, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
+    method public android.service.autofill.SaveInfo.Builder setTriggerId(android.view.autofill.AutofillId);
     method public android.service.autofill.SaveInfo.Builder setValidator(android.service.autofill.Validator);
   }
 
@@ -43543,8 +43561,12 @@
     field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
     field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload";
     field public static final int RESULT_CANCELLED = 2; // 0x2
+    field public static final int RESULT_DOWNLOAD_FAILURE = 6; // 0x6
     field public static final int RESULT_EXPIRED = 3; // 0x3
+    field public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; // 0x8
     field public static final int RESULT_IO_ERROR = 4; // 0x4
+    field public static final int RESULT_OUT_OF_STORAGE = 7; // 0x7
+    field public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; // 0x5
     field public static final int RESULT_SUCCESSFUL = 1; // 0x1
     field public static final int STATUS_ACTIVELY_DOWNLOADING = 1; // 0x1
     field public static final int STATUS_PENDING_DOWNLOAD = 2; // 0x2
@@ -44330,13 +44352,12 @@
   }
 
   public static class DownloadRequest.Builder {
-    ctor public DownloadRequest.Builder();
+    ctor public DownloadRequest.Builder(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest build();
     method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
     method public android.telephony.mbms.DownloadRequest.Builder setOpaqueData(byte[]);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceId(java.lang.String);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
-    method public android.telephony.mbms.DownloadRequest.Builder setSource(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
   }
 
@@ -49471,8 +49492,8 @@
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
     method public void bringToFront();
-    method public void buildDrawingCache();
-    method public void buildDrawingCache(boolean);
+    method public deprecated void buildDrawingCache();
+    method public deprecated void buildDrawingCache(boolean);
     method public void buildLayer();
     method public boolean callOnClick();
     method public boolean canResolveLayoutDirection();
@@ -49497,7 +49518,7 @@
     method protected int computeVerticalScrollRange();
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo();
     method public void createContextMenu(android.view.ContextMenu);
-    method public void destroyDrawingCache();
+    method public deprecated void destroyDrawingCache();
     method public android.view.WindowInsets dispatchApplyWindowInsets(android.view.WindowInsets);
     method public boolean dispatchCapturedPointerEvent(android.view.MotionEvent);
     method public void dispatchConfigurationChanged(android.content.res.Configuration);
@@ -49578,10 +49599,10 @@
     method public static int getDefaultSize(int, int);
     method public android.view.Display getDisplay();
     method public final int[] getDrawableState();
-    method public android.graphics.Bitmap getDrawingCache();
-    method public android.graphics.Bitmap getDrawingCache(boolean);
-    method public int getDrawingCacheBackgroundColor();
-    method public int getDrawingCacheQuality();
+    method public deprecated android.graphics.Bitmap getDrawingCache();
+    method public deprecated android.graphics.Bitmap getDrawingCache(boolean);
+    method public deprecated int getDrawingCacheBackgroundColor();
+    method public deprecated int getDrawingCacheQuality();
     method public void getDrawingRect(android.graphics.Rect);
     method public long getDrawingTime();
     method public float getElevation();
@@ -49720,7 +49741,7 @@
     method public boolean isClickable();
     method public boolean isContextClickable();
     method public boolean isDirty();
-    method public boolean isDrawingCacheEnabled();
+    method public deprecated boolean isDrawingCacheEnabled();
     method public boolean isDuplicateParentStateEnabled();
     method public boolean isEnabled();
     method public final boolean isFocusable();
@@ -49891,9 +49912,9 @@
     method public void setContentDescription(java.lang.CharSequence);
     method public void setContextClickable(boolean);
     method public void setDefaultFocusHighlightEnabled(boolean);
-    method public void setDrawingCacheBackgroundColor(int);
-    method public void setDrawingCacheEnabled(boolean);
-    method public void setDrawingCacheQuality(int);
+    method public deprecated void setDrawingCacheBackgroundColor(int);
+    method public deprecated void setDrawingCacheEnabled(boolean);
+    method public deprecated void setDrawingCacheQuality(int);
     method public void setDuplicateParentStateEnabled(boolean);
     method public void setElevation(float);
     method public void setEnabled(boolean);
@@ -50044,9 +50065,9 @@
     field public static final int DRAG_FLAG_GLOBAL_URI_READ = 1; // 0x1
     field public static final int DRAG_FLAG_GLOBAL_URI_WRITE = 2; // 0x2
     field public static final int DRAG_FLAG_OPAQUE = 512; // 0x200
-    field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
-    field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
-    field public static final int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
+    field public static final deprecated int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
+    field public static final deprecated int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
+    field public static final deprecated int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
     field protected static final int[] EMPTY_STATE_SET;
     field protected static final int[] ENABLED_FOCUSED_SELECTED_STATE_SET;
     field protected static final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
@@ -50438,7 +50459,7 @@
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
     method public android.view.ViewGroupOverlay getOverlay();
-    method public int getPersistentDrawingCache();
+    method public deprecated int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
     method public final deprecated void invalidateChild(android.view.View, android.graphics.Rect);
@@ -50491,7 +50512,7 @@
     method public void setAddStatesFromChildren(boolean);
     method public deprecated void setAlwaysDrawnWithCacheEnabled(boolean);
     method public deprecated void setAnimationCacheEnabled(boolean);
-    method protected void setChildrenDrawingCacheEnabled(boolean);
+    method protected deprecated void setChildrenDrawingCacheEnabled(boolean);
     method protected void setChildrenDrawingOrderEnabled(boolean);
     method protected deprecated void setChildrenDrawnWithCacheEnabled(boolean);
     method public void setClipChildren(boolean);
@@ -50503,7 +50524,7 @@
     method public void setLayoutTransition(android.animation.LayoutTransition);
     method public void setMotionEventSplittingEnabled(boolean);
     method public void setOnHierarchyChangeListener(android.view.ViewGroup.OnHierarchyChangeListener);
-    method public void setPersistentDrawingCache(int);
+    method public deprecated void setPersistentDrawingCache(int);
     method protected void setStaticTransformationsEnabled(boolean);
     method public void setTouchscreenBlocksFocus(boolean);
     method public void setTransitionGroup(boolean);
@@ -50521,10 +50542,10 @@
     field public static final int FOCUS_BLOCK_DESCENDANTS = 393216; // 0x60000
     field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
     field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
-    field public static final int PERSISTENT_ALL_CACHES = 3; // 0x3
-    field public static final int PERSISTENT_ANIMATION_CACHE = 1; // 0x1
-    field public static final int PERSISTENT_NO_CACHE = 0; // 0x0
-    field public static final int PERSISTENT_SCROLLING_CACHE = 2; // 0x2
+    field public static final deprecated int PERSISTENT_ALL_CACHES = 3; // 0x3
+    field public static final deprecated int PERSISTENT_ANIMATION_CACHE = 1; // 0x1
+    field public static final deprecated int PERSISTENT_NO_CACHE = 0; // 0x0
+    field public static final deprecated int PERSISTENT_SCROLLING_CACHE = 2; // 0x2
   }
 
   public static class ViewGroup.LayoutParams {
@@ -50722,6 +50743,9 @@
     method public abstract void setInputType(int);
     method public abstract void setLocaleList(android.os.LocaleList);
     method public abstract void setLongClickable(boolean);
+    method public abstract void setMaxTextEms(int);
+    method public abstract void setMaxTextLength(int);
+    method public abstract void setMinTextEms(int);
     method public abstract void setOpaque(boolean);
     method public abstract void setSelected(boolean);
     method public abstract void setText(java.lang.CharSequence);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 7ee261e..639877f 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -275,6 +275,10 @@
     method public android.media.tv.TvInputManager.Hardware acquireTvInputHardware(int, android.media.tv.TvInputManager.HardwareCallback, android.media.tv.TvInputInfo);
   }
 
+  public static final class TvInputManager.Hardware {
+    method public boolean dispatchKeyEventToHdmi(android.view.KeyEvent);
+  }
+
   public class TvView extends android.view.ViewGroup {
     method public void requestUnblockContent(android.media.tv.TvContentRating);
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index 91b47d5..cb4a6f2 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -362,6 +362,7 @@
     field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
     field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
     field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
+    field public static final int cantSaveState = 16844142; // 0x101056e
     field public static final deprecated int capitalize = 16843113; // 0x1010169
     field public static final int category = 16843752; // 0x10103e8
     field public static final int centerBright = 16842956; // 0x10100cc
@@ -4042,6 +4043,7 @@
   public class ActivityOptions {
     method public android.graphics.Rect getLaunchBounds();
     method public int getLaunchDisplayId();
+    method public boolean getLockTaskMode();
     method public static android.app.ActivityOptions makeBasic();
     method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -4057,6 +4059,7 @@
     method public android.app.ActivityOptions setLaunchDisplayId(int);
     method public void setLaunchTaskId(int);
     method public void setLaunchWindowingMode(int);
+    method public android.app.ActivityOptions setLockTaskMode(boolean);
     method public void setTaskOverlay(boolean, boolean);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
@@ -5669,8 +5672,10 @@
     method public static java.lang.String suppressedEffectsToString(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.NotificationManager.Policy> CREATOR;
+    field public static final int PRIORITY_CATEGORY_ALARMS = 32; // 0x20
     field public static final int PRIORITY_CATEGORY_CALLS = 8; // 0x8
     field public static final int PRIORITY_CATEGORY_EVENTS = 2; // 0x2
+    field public static final int PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER = 64; // 0x40
     field public static final int PRIORITY_CATEGORY_MESSAGES = 4; // 0x4
     field public static final int PRIORITY_CATEGORY_REMINDERS = 1; // 0x1
     field public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 16; // 0x10
@@ -6738,6 +6743,9 @@
     method public int getInputType();
     method public int getLeft();
     method public android.os.LocaleList getLocaleList();
+    method public int getMaxTextEms();
+    method public int getMaxTextLength();
+    method public int getMinTextEms();
     method public int getScrollX();
     method public int getScrollY();
     method public java.lang.CharSequence getText();
@@ -10508,6 +10516,7 @@
     method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
     method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(java.util.List<java.lang.String>);
     field public static final int FLAG_GET_KEY_FIELDS_ONLY = 4; // 0x4
+    field public static final int FLAG_MATCH_ALL_PINNED = 1024; // 0x400
     field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
     field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
     field public static final int FLAG_MATCH_PINNED = 2; // 0x2
@@ -11080,6 +11089,7 @@
     method public android.content.ComponentName getActivity();
     method public java.util.Set<java.lang.String> getCategories();
     method public java.lang.CharSequence getDisabledMessage();
+    method public int getDisabledReason();
     method public android.os.PersistableBundle getExtras();
     method public java.lang.String getId();
     method public android.content.Intent getIntent();
@@ -11096,8 +11106,16 @@
     method public boolean isEnabled();
     method public boolean isImmutable();
     method public boolean isPinned();
+    method public boolean isVisibleToPublisher();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.pm.ShortcutInfo> CREATOR;
+    field public static final int DISABLED_REASON_APP_CHANGED = 2; // 0x2
+    field public static final int DISABLED_REASON_BACKUP_NOT_SUPPORTED = 101; // 0x65
+    field public static final int DISABLED_REASON_BY_APP = 1; // 0x1
+    field public static final int DISABLED_REASON_NOT_DISABLED = 0; // 0x0
+    field public static final int DISABLED_REASON_OTHER_RESTORE_ISSUE = 103; // 0x67
+    field public static final int DISABLED_REASON_SIGNATURE_MISMATCH = 102; // 0x66
+    field public static final int DISABLED_REASON_VERSION_LOWER = 100; // 0x64
     field public static final java.lang.String SHORTCUT_CATEGORY_CONVERSATION = "android.shortcut.conversation";
   }
 
@@ -32097,6 +32115,7 @@
     field public static final java.lang.String DISALLOW_SET_WALLPAPER = "no_set_wallpaper";
     field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
     field public static final java.lang.String DISALLOW_SMS = "no_sms";
+    field public static final java.lang.String DISALLOW_SYSTEM_ERROR_DIALOGS = "no_system_error_dialogs";
     field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
     field public static final java.lang.String DISALLOW_UNMUTE_MICROPHONE = "no_unmute_microphone";
     field public static final java.lang.String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";
@@ -37533,6 +37552,7 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
+    field public static final int FLAG_DONT_SAVE_ON_FINISH = 2; // 0x2
     field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1
     field public static final int NEGATIVE_BUTTON_STYLE_CANCEL = 0; // 0x0
     field public static final int NEGATIVE_BUTTON_STYLE_REJECT = 1; // 0x1
@@ -37554,6 +37574,7 @@
     method public android.service.autofill.SaveInfo.Builder setFlags(int);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(int, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
+    method public android.service.autofill.SaveInfo.Builder setTriggerId(android.view.autofill.AutofillId);
     method public android.service.autofill.SaveInfo.Builder setValidator(android.service.autofill.Validator);
   }
 
@@ -40414,8 +40435,12 @@
     field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT";
     field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
     field public static final int RESULT_CANCELLED = 2; // 0x2
+    field public static final int RESULT_DOWNLOAD_FAILURE = 6; // 0x6
     field public static final int RESULT_EXPIRED = 3; // 0x3
+    field public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; // 0x8
     field public static final int RESULT_IO_ERROR = 4; // 0x4
+    field public static final int RESULT_OUT_OF_STORAGE = 7; // 0x7
+    field public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; // 0x5
     field public static final int RESULT_SUCCESSFUL = 1; // 0x1
     field public static final int STATUS_ACTIVELY_DOWNLOADING = 1; // 0x1
     field public static final int STATUS_PENDING_DOWNLOAD = 2; // 0x2
@@ -41082,11 +41107,10 @@
   }
 
   public static class DownloadRequest.Builder {
-    ctor public DownloadRequest.Builder();
+    ctor public DownloadRequest.Builder(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest build();
     method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
-    method public android.telephony.mbms.DownloadRequest.Builder setSource(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
   }
 
@@ -46315,8 +46339,8 @@
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
     method public void bringToFront();
-    method public void buildDrawingCache();
-    method public void buildDrawingCache(boolean);
+    method public deprecated void buildDrawingCache();
+    method public deprecated void buildDrawingCache(boolean);
     method public void buildLayer();
     method public boolean callOnClick();
     method public boolean canResolveLayoutDirection();
@@ -46341,7 +46365,7 @@
     method protected int computeVerticalScrollRange();
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo();
     method public void createContextMenu(android.view.ContextMenu);
-    method public void destroyDrawingCache();
+    method public deprecated void destroyDrawingCache();
     method public android.view.WindowInsets dispatchApplyWindowInsets(android.view.WindowInsets);
     method public boolean dispatchCapturedPointerEvent(android.view.MotionEvent);
     method public void dispatchConfigurationChanged(android.content.res.Configuration);
@@ -46422,10 +46446,10 @@
     method public static int getDefaultSize(int, int);
     method public android.view.Display getDisplay();
     method public final int[] getDrawableState();
-    method public android.graphics.Bitmap getDrawingCache();
-    method public android.graphics.Bitmap getDrawingCache(boolean);
-    method public int getDrawingCacheBackgroundColor();
-    method public int getDrawingCacheQuality();
+    method public deprecated android.graphics.Bitmap getDrawingCache();
+    method public deprecated android.graphics.Bitmap getDrawingCache(boolean);
+    method public deprecated int getDrawingCacheBackgroundColor();
+    method public deprecated int getDrawingCacheQuality();
     method public void getDrawingRect(android.graphics.Rect);
     method public long getDrawingTime();
     method public float getElevation();
@@ -46566,7 +46590,7 @@
     method public boolean isContextClickable();
     method public boolean isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
     method public boolean isDirty();
-    method public boolean isDrawingCacheEnabled();
+    method public deprecated boolean isDrawingCacheEnabled();
     method public boolean isDuplicateParentStateEnabled();
     method public boolean isEnabled();
     method public final boolean isFocusable();
@@ -46740,9 +46764,9 @@
     method public void setContentDescription(java.lang.CharSequence);
     method public void setContextClickable(boolean);
     method public void setDefaultFocusHighlightEnabled(boolean);
-    method public void setDrawingCacheBackgroundColor(int);
-    method public void setDrawingCacheEnabled(boolean);
-    method public void setDrawingCacheQuality(int);
+    method public deprecated void setDrawingCacheBackgroundColor(int);
+    method public deprecated void setDrawingCacheEnabled(boolean);
+    method public deprecated void setDrawingCacheQuality(int);
     method public void setDuplicateParentStateEnabled(boolean);
     method public void setElevation(float);
     method public void setEnabled(boolean);
@@ -46894,9 +46918,9 @@
     field public static final int DRAG_FLAG_GLOBAL_URI_READ = 1; // 0x1
     field public static final int DRAG_FLAG_GLOBAL_URI_WRITE = 2; // 0x2
     field public static final int DRAG_FLAG_OPAQUE = 512; // 0x200
-    field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
-    field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
-    field public static final int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
+    field public static final deprecated int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
+    field public static final deprecated int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
+    field public static final deprecated int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
     field protected static final int[] EMPTY_STATE_SET;
     field protected static final int[] ENABLED_FOCUSED_SELECTED_STATE_SET;
     field protected static final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
@@ -47292,7 +47316,7 @@
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
     method public android.view.ViewGroupOverlay getOverlay();
-    method public int getPersistentDrawingCache();
+    method public deprecated int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
     method public final deprecated void invalidateChild(android.view.View, android.graphics.Rect);
@@ -47345,7 +47369,7 @@
     method public void setAddStatesFromChildren(boolean);
     method public deprecated void setAlwaysDrawnWithCacheEnabled(boolean);
     method public deprecated void setAnimationCacheEnabled(boolean);
-    method protected void setChildrenDrawingCacheEnabled(boolean);
+    method protected deprecated void setChildrenDrawingCacheEnabled(boolean);
     method protected void setChildrenDrawingOrderEnabled(boolean);
     method protected deprecated void setChildrenDrawnWithCacheEnabled(boolean);
     method public void setClipChildren(boolean);
@@ -47357,7 +47381,7 @@
     method public void setLayoutTransition(android.animation.LayoutTransition);
     method public void setMotionEventSplittingEnabled(boolean);
     method public void setOnHierarchyChangeListener(android.view.ViewGroup.OnHierarchyChangeListener);
-    method public void setPersistentDrawingCache(int);
+    method public deprecated void setPersistentDrawingCache(int);
     method protected void setStaticTransformationsEnabled(boolean);
     method public void setTouchscreenBlocksFocus(boolean);
     method public void setTransitionGroup(boolean);
@@ -47375,10 +47399,10 @@
     field public static final int FOCUS_BLOCK_DESCENDANTS = 393216; // 0x60000
     field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
     field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
-    field public static final int PERSISTENT_ALL_CACHES = 3; // 0x3
-    field public static final int PERSISTENT_ANIMATION_CACHE = 1; // 0x1
-    field public static final int PERSISTENT_NO_CACHE = 0; // 0x0
-    field public static final int PERSISTENT_SCROLLING_CACHE = 2; // 0x2
+    field public static final deprecated int PERSISTENT_ALL_CACHES = 3; // 0x3
+    field public static final deprecated int PERSISTENT_ANIMATION_CACHE = 1; // 0x1
+    field public static final deprecated int PERSISTENT_NO_CACHE = 0; // 0x0
+    field public static final deprecated int PERSISTENT_SCROLLING_CACHE = 2; // 0x2
   }
 
   public static class ViewGroup.LayoutParams {
@@ -47576,6 +47600,9 @@
     method public abstract void setInputType(int);
     method public abstract void setLocaleList(android.os.LocaleList);
     method public abstract void setLongClickable(boolean);
+    method public abstract void setMaxTextEms(int);
+    method public abstract void setMaxTextLength(int);
+    method public abstract void setMinTextEms(int);
     method public abstract void setOpaque(boolean);
     method public abstract void setSelected(boolean);
     method public abstract void setText(java.lang.CharSequence);
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index b16188e..e5d35b3 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -34,13 +34,6 @@
     iot/BootAction.cpp \
     iot/BootParameters.cpp \
 
-LOCAL_SHARED_LIBRARIES += \
-    libandroidthings \
-    libbase \
-    libbinder \
-
-LOCAL_STATIC_LIBRARIES += cpufeatures
-
 else
 
 LOCAL_SRC_FILES += \
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 6526123..d1af71d 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -260,9 +260,9 @@
     sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
             dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
 
-    SurfaceComposerClient::openGlobalTransaction();
-    control->setLayer(0x40000000);
-    SurfaceComposerClient::closeGlobalTransaction();
+    SurfaceComposerClient::Transaction t;
+    t.setLayer(control, 0x40000000)
+        .apply();
 
     sp<Surface> s = control->getSurface();
 
diff --git a/cmds/bootanimation/iot/iotbootanimation_main.cpp b/cmds/bootanimation/iot/iotbootanimation_main.cpp
index 742f9c24..00cef43 100644
--- a/cmds/bootanimation/iot/iotbootanimation_main.cpp
+++ b/cmds/bootanimation/iot/iotbootanimation_main.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "IotBootAnimation"
 
-#include <android-base/file.h>
+#include <base/files/file_util.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
@@ -31,13 +31,14 @@
 #include "BootParameters.h"
 
 using namespace android;
-using android::base::ReadFileToString;
 
 // Create a typedef for readability.
 typedef android::BootAnimation::Animation Animation;
 
 namespace {
 
+constexpr const char* kDefaultLibName = "libbootaction.so";
+
 class BootActionAnimationCallbacks : public android::BootAnimation::Callbacks {
 public:
     BootActionAnimationCallbacks(std::unique_ptr<BootParameters> bootParameters)
@@ -49,11 +50,13 @@
         // This value is optionally provided by the user and will be written to
         // /oem/oem.prop.
         char property[PROP_VALUE_MAX] = {0};
-        if (property_get("ro.oem.bootactions.lib", property, "") < 1) {
-            ALOGI("No bootaction specified");
+        property_get("ro.oem.bootactions.lib", property, kDefaultLibName);
+        library_path += property;
+
+        if (!::base::PathExists(::base::FilePath(library_path))) {
+            ALOGI("Skipping boot actions: %s does not exist", library_path.c_str());
             return;
         }
-        library_path += property;
 
         mBootAction = new BootAction();
         if (!mBootAction->init(library_path, mBootParameters->getParameters())) {
diff --git a/cmds/incidentd/src/PrivacyBuffer.cpp b/cmds/incidentd/src/PrivacyBuffer.cpp
index 07a064cf..37f6ed7 100644
--- a/cmds/incidentd/src/PrivacyBuffer.cpp
+++ b/cmds/incidentd/src/PrivacyBuffer.cpp
@@ -33,18 +33,18 @@
 {
     EncodedBuffer::Pointer snapshot = iter->rp()->copy();
     size_t bytesToWrite = 0;
-    uint32_t varint = 0;
+    uint64_t varint = 0;
     switch (wireType) {
         case WIRE_TYPE_VARINT:
             varint = iter->readRawVarint();
-            if(!skip) return buf->writeRawVarint(varint);
+            if(!skip) return buf->writeRawVarint64(varint);
             break;
         case WIRE_TYPE_FIXED64:
             bytesToWrite = 8;
             break;
         case WIRE_TYPE_LENGTH_DELIMITED:
             bytesToWrite = iter->readRawVarint();
-            if(!skip) buf->writeRawVarint(bytesToWrite);
+            if(!skip) buf->writeRawVarint32(bytesToWrite);
             break;
         case WIRE_TYPE_FIXED32:
             bytesToWrite = 4;
@@ -76,7 +76,6 @@
     uint8_t wireType = read_wire_type(varint);
     uint32_t fieldId = read_field_id(varint);
     const Privacy* policy = parentPolicy->lookup(fieldId);
-
     if (policy == NULL || !policy->IsMessageType() || !policy->HasChildren()) {
         bool skip = !spec.CheckPremission(policy);
         size_t amt = buf->size();
@@ -99,7 +98,7 @@
     }
 
     buf->writeHeader(fieldId, wireType);
-    buf->writeRawVarint(finalSize);
+    buf->writeRawVarint32(finalSize);
     while (!q.empty()) {
         EncodedBuffer* subField = q.front();
         EncodedBuffer::iterator it = subField->begin();
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index e7a31a0..4c95007 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -42,23 +42,7 @@
 LOCAL_SRC_FILES := \
     ../../core/java/android/os/IStatsCompanionService.aidl \
     ../../core/java/android/os/IStatsManager.aidl \
-    src/StatsService.cpp \
-    src/AnomalyMonitor.cpp \
-    src/StatsPuller.cpp \
-    src/LogEntryPrinter.cpp \
-    src/LogReader.cpp \
-    src/main.cpp \
-    src/DropboxWriter.cpp \
-    src/parse_util.cpp \
-    src/StatsLogProcessor.cpp \
-    src/stats_log.proto \
-    src/statsd_config.proto \
-    src/DropboxReader.cpp \
-    src/matchers/LogEntryMatcherManager.cpp \
-    src/metrics/CountMetricProducer.cpp \
-    src/metrics/ConditionTracker.cpp \
-    src/metrics/MetricsManager.cpp \
-    src/metrics/CountAnomalyTracker.cpp \
+    $(call all-cpp-files-under,src) \
 
 LOCAL_CFLAGS += \
     -Wall \
@@ -128,13 +112,21 @@
     ../../core/java/android/os/IStatsCompanionService.aidl \
     ../../core/java/android/os/IStatsManager.aidl \
     src/StatsService.cpp \
-    tests/indexed_priority_queue_test.cpp \
-    src/parse_util.cpp \
+    src/AnomalyMonitor.cpp \
+    src/stats_util.cpp \
     src/LogEntryPrinter.cpp \
     src/LogReader.cpp \
-    src/matchers/LogEntryMatcherManager.cpp \
-    tests/LogReader_test.cpp \
-    tests/LogEntryMatcher_test.cpp \
+    src/matchers/matcher_util.cpp \
+    src/condition/SimpleConditionTracker.cpp \
+    src/condition/CombinationConditionTracker.cpp \
+    src/matchers/SimpleLogMatchingTracker.cpp \
+    src/matchers/CombinationLogMatchingTracker.cpp \
+    src/metrics/metrics_manager_util.cpp \
+    src/metrics/CountMetricProducer.cpp \
+    src/metrics/CountAnomalyTracker.cpp \
+    src/condition/condition_util.cpp \
+    src/UidMap.cpp \
+    $(call all-cpp-files-under, tests) \
 
 LOCAL_STATIC_LIBRARIES := \
     libgmock \
diff --git a/cmds/statsd/src/AnomalyMonitor.cpp b/cmds/statsd/src/AnomalyMonitor.cpp
index 92fe844..4fbbc7a 100644
--- a/cmds/statsd/src/AnomalyMonitor.cpp
+++ b/cmds/statsd/src/AnomalyMonitor.cpp
@@ -90,6 +90,36 @@
     }
 }
 
+// More efficient than repeatedly calling remove(mPq.top()) since it batches the
+// updates to the registered alarm.
+unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>
+                AnomalyMonitor::popSoonerThan(uint32_t timestampSec) {
+
+    if (DEBUG) ALOGD("Removing alarms with time <= %u", timestampSec);
+    unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> oldAlarms;
+    std::lock_guard<std::mutex> lock(mLock);
+
+    for (sp<const AnomalyAlarm> t = mPq.top();
+                t != nullptr && t->timestampSec <= timestampSec; t = mPq.top()) {
+        oldAlarms.insert(t);
+        mPq.pop(); // remove t
+    }
+    // Always update registered alarm time (if anything has changed).
+    if (!oldAlarms.empty()) {
+        if (mPq.empty()) {
+            if (DEBUG) ALOGD("Queue is empty. Cancel any alarm.");
+            mRegisteredAlarmTimeSec = 0;
+            if (mStatsCompanionService != nullptr) {
+                mStatsCompanionService->cancelAnomalyAlarm();
+            }
+        } else {
+            // Always update the registered alarm in this case (unlike remove()).
+            updateRegisteredAlarmTime_l(mPq.top()->timestampSec);
+        }
+    }
+    return oldAlarms;
+}
+
 void AnomalyMonitor::updateRegisteredAlarmTime_l(uint32_t timestampSec) {
     if (DEBUG) ALOGD("Updating reg alarm time to %u", timestampSec);
     mRegisteredAlarmTimeSec = timestampSec;
diff --git a/cmds/statsd/src/AnomalyMonitor.h b/cmds/statsd/src/AnomalyMonitor.h
index d78be54..7c6e5e8 100644
--- a/cmds/statsd/src/AnomalyMonitor.h
+++ b/cmds/statsd/src/AnomalyMonitor.h
@@ -21,12 +21,14 @@
 #include <indexed_priority_queue.h>
 #include <utils/RefBase.h>
 
+#include <unordered_set>
 #include <queue>
 #include <vector>
 
 using namespace android;
 
 using android::os::IStatsCompanionService;
+using std::unordered_set;
 
 namespace android {
 namespace os {
@@ -86,6 +88,13 @@
     void remove(sp<const AnomalyAlarm> alarm);
 
     /**
+     * Returns and removes all alarms whose timestamp <= the given timestampSec.
+     * Always updates the registered alarm if return is non-empty.
+     */
+    unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>
+                    popSoonerThan(uint32_t timestampSec);
+
+    /**
      * Returns the projected alarm timestamp that is registered with
      * StatsCompanionService. This may not be equal to the soonest alarm,
      * but should be within minDiffToUpdateRegisteredAlarmTimeSec of it.
diff --git a/cmds/statsd/src/KernelWakelockPuller.cpp b/cmds/statsd/src/KernelWakelockPuller.cpp
new file mode 100644
index 0000000..1798f9d
--- /dev/null
+++ b/cmds/statsd/src/KernelWakelockPuller.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "KernelWakelockPuller.h"
+#include <android/os/IStatsCompanionService.h>
+#include <binder/IPCThreadState.h>
+#include <cutils/log.h>
+#include <private/android_filesystem_config.h>
+#include "StatsPuller.h"
+#include "StatsService.h"
+
+using namespace android;
+using namespace android::base;
+using namespace android::binder;
+using namespace android::os;
+using namespace std;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+const int KernelWakelockPuller::PULL_CODE_KERNEL_WAKELOCKS = 20;
+
+// The reading and parsing are implemented in Java. It is not difficult to port over. But for now
+// let StatsCompanionService handle that and send the data back.
+String16 KernelWakelockPuller::pull() {
+    sp<IStatsCompanionService> statsCompanion = StatsService::getStatsCompanionService();
+    String16 returned_value("");
+    if (statsCompanion != NULL) {
+      Status status = statsCompanion->pullData(KernelWakelockPuller::PULL_CODE_KERNEL_WAKELOCKS,
+                                             &returned_value);
+      if (!status.isOk()) {
+          ALOGW("error pulling kernel wakelock");
+      }
+      ALOGD("KernelWakelockPuller::pull succeeded!");
+      // TODO: remove this when we integrate into aggregation chain.
+      ALOGD("%s", String8(returned_value).string());
+      return returned_value;
+    } else {
+        ALOGW("statsCompanion not found!");
+        return String16();
+    }
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/parse_util.h b/cmds/statsd/src/KernelWakelockPuller.h
similarity index 65%
copy from cmds/statsd/src/parse_util.h
copy to cmds/statsd/src/KernelWakelockPuller.h
index 8b82e7b..1c16f87 100644
--- a/cmds/statsd/src/parse_util.h
+++ b/cmds/statsd/src/KernelWakelockPuller.h
@@ -13,24 +13,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef PARSE_UTIL_H
-#define PARSE_UTIL_H
 
-#include "DropboxWriter.h"
-#include "LogReader.h"
+#ifndef STATSD_KERNELWAKELOCKPULLER_H
+#define STATSD_KERNELWAKELOCKPULLER_H
 
-#include <log/logprint.h>
+#include <utils/String16.h>
+#include "StatsPuller.h"
 
 namespace android {
 namespace os {
 namespace statsd {
 
-EventMetricData parse(log_msg msg);
-
-int getTagId(log_msg msg);
+class KernelWakelockPuller : public StatsPuller {
+public:
+    // a number of stats need to be pulled from StatsCompanionService
+    //
+    const static int PULL_CODE_KERNEL_WAKELOCKS;
+    String16 pull() override;
+};
 
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
 
-#endif  // PARSE_UTIL_H
+#endif  // STATSD_KERNELWAKELOCKPULLER_H
diff --git a/cmds/statsd/src/PackageInfoListener.h b/cmds/statsd/src/PackageInfoListener.h
new file mode 100644
index 0000000..476c1d9
--- /dev/null
+++ b/cmds/statsd/src/PackageInfoListener.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef STATSD_PACKAGE_INFO_LISTENER_H
+#define STATSD_PACKAGE_INFO_LISTENER_H
+
+#include <utils/RefBase.h>
+#include <string>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class PackageInfoListener : public virtual android::RefBase {
+public:
+    // Uid map will notify this listener that the app with apk name and uid has been upgraded to
+    // the specified version.
+    virtual void notifyAppUpgrade(const std::string& apk, const int uid, const int version) = 0;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+
+#endif //STATSD_PACKAGE_INFO_LISTENER_H
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 117fb5e..f877ef3 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -20,7 +20,6 @@
 #include <frameworks/base/cmds/statsd/src/stats_log.pb.h>
 #include <log/log_event_list.h>
 #include <metrics/CountMetricProducer.h>
-#include <parse_util.h>
 #include <utils/Errors.h>
 
 using namespace android;
@@ -32,7 +31,9 @@
 namespace os {
 namespace statsd {
 
-StatsLogProcessor::StatsLogProcessor() : m_dropbox_writer("all-logs") {
+StatsLogProcessor::StatsLogProcessor(const sp<UidMap> &uidMap)
+        : m_dropbox_writer("all-logs"), m_UidMap(uidMap)
+{
     // hardcoded config
     // this should be called from StatsService when it receives a statsd_config
     UpdateConfig(0, buildFakeConfig());
@@ -41,28 +42,6 @@
 StatsLogProcessor::~StatsLogProcessor() {
 }
 
-StatsdConfig StatsLogProcessor::buildFakeConfig() {
-    // HACK: Hard code a test metric for counting screen on events...
-    StatsdConfig config;
-    config.set_config_id(12345L);
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_metric_id(20150717L);
-    metric->set_what("SCREEN_IS_ON");
-    metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
-
-    LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
-    eventMatcher->set_name("SCREEN_IS_ON");
-
-    SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
-    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
-    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()
-            ->set_key(1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleLogEntryMatcher->mutable_key_value_matcher(0)
-            ->set_eq_int(2/*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-    return config;
-}
-
 // TODO: what if statsd service restarts? How do we know what logs are already processed before?
 void StatsLogProcessor::OnLogEvent(const log_msg& msg) {
     // TODO: Use EventMetric to filter the events we want to log.
@@ -83,7 +62,14 @@
 
     ALOGD("Updated configuration for source %i", config_source);
 
-    mMetricsManagers.insert({config_source, std::make_unique<MetricsManager>(config)});
+    unique_ptr<MetricsManager> newMetricsManager = std::make_unique<MetricsManager>(config);
+    if (newMetricsManager->isConfigValid()) {
+        mMetricsManagers.insert({config_source, std::move(newMetricsManager)});
+        ALOGD("StatsdConfig valid");
+    } else {
+        // If there is any error in the config, don't use it.
+        ALOGD("StatsdConfig NOT valid");
+    }
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 88c63fa..05e441c 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -16,11 +16,12 @@
 #ifndef STATS_LOG_PROCESSOR_H
 #define STATS_LOG_PROCESSOR_H
 
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 #include "DropboxWriter.h"
 #include "LogReader.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 #include "metrics/MetricsManager.h"
-#include "parse_util.h"
+#include "stats_util.h"
+#include "UidMap.h"
 
 #include <log/logprint.h>
 #include <stdio.h>
@@ -32,7 +33,7 @@
 
 class StatsLogProcessor : public LogListener {
 public:
-    StatsLogProcessor();
+    StatsLogProcessor(const sp<UidMap> &uidMap);
     virtual ~StatsLogProcessor();
 
     virtual void OnLogEvent(const log_msg& msg);
@@ -45,7 +46,7 @@
 
     std::unordered_map<int, std::unique_ptr<MetricsManager>> mMetricsManagers;
 
-    static StatsdConfig buildFakeConfig();
+    sp<UidMap> m_UidMap; // Reference to the UidMap to lookup app name and version for each uid.
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/StatsPuller.cpp b/cmds/statsd/src/StatsPuller.cpp
deleted file mode 100644
index 94e8361..0000000
--- a/cmds/statsd/src/StatsPuller.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#define LOG_TAG "StatsPuller"
-#define DEBUG true
-
-#include "StatsPuller.h"
-#include "StatsService.h"
-#include <android/os/IStatsCompanionService.h>
-#include <cutils/log.h>
-
-using namespace android;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-String16 StatsPuller::pull(int pullCode) {
-    if (DEBUG) ALOGD("Initiating pulling %d", pullCode);
-
-    switch (pullCode) {
-        // All stats_companion_service cases go here with fallthroughs
-        case PULL_CODE_KERNEL_WAKELOCKS: {
-            // TODO: Consider caching the statsCompanion service
-            sp <IStatsCompanionService>
-                    statsCompanion = StatsService::getStatsCompanionService();
-            String16 returned_value("");
-            Status status = statsCompanion->pullData(pullCode, &returned_value);
-            if (DEBUG) ALOGD("Finished pulling the data");
-            if (!status.isOk()) {
-                ALOGW("error pulling data of type %d", pullCode);
-            }
-            return returned_value;
-        }
-
-        // case OTHER_TYPES: etc.
-
-        default: {
-            ALOGE("invalid pull code %d", pullCode);
-            return String16("");
-        }
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/StatsPuller.h b/cmds/statsd/src/StatsPuller.h
index 05343b5..5e556b8 100644
--- a/cmds/statsd/src/StatsPuller.h
+++ b/cmds/statsd/src/StatsPuller.h
@@ -25,19 +25,13 @@
 
 class StatsPuller {
 public:
-    // Enums of pulled data types (pullCodes)
-    // These values must be kept in sync with com/android/server/stats/StatsCompanionService.java.
-    // TODO: pull the constant from stats_events.proto instead
-    const static int PULL_CODE_KERNEL_WAKELOCKS = 20;
-
-    StatsPuller();
-    ~StatsPuller();
-
-    static String16 pull(int pullCode);
+    virtual ~StatsPuller(){};
+    // use string for now, until we figure out how to integrate into the aggregation path
+    virtual String16 pull() = 0;
 };
 
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
 
-#endif //STATSD_STATSPULLER_H
+#endif  // STATSD_STATSPULLER_H
diff --git a/cmds/statsd/src/StatsPullerManager.cpp b/cmds/statsd/src/StatsPullerManager.cpp
new file mode 100644
index 0000000..f4cf1ce
--- /dev/null
+++ b/cmds/statsd/src/StatsPullerManager.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "StatsPullerManager"
+#define DEBUG true
+
+#include "StatsPullerManager.h"
+#include <android/os/IStatsCompanionService.h>
+#include <cutils/log.h>
+#include "StatsService.h"
+#include "KernelWakelockPuller.h"
+
+
+using namespace android;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+const int StatsPullerManager::KERNEL_WAKELOCKS = 1;
+
+StatsPullerManager::StatsPullerManager() {
+    mStatsPullers.insert(
+            {static_cast<int>(KERNEL_WAKELOCKS), std::make_unique<KernelWakelockPuller>()});
+}
+
+String16 StatsPullerManager::pull(int pullCode) {
+    if (DEBUG) ALOGD("Initiating pulling %d", pullCode);
+    if (mStatsPullers.find(pullCode) != mStatsPullers.end()) {
+        return (mStatsPullers.find(pullCode)->second)->pull();
+    } else {
+        ALOGD("Unknown pull code %d", pullCode);
+        return String16();
+    }
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/StatsPullerManager.h b/cmds/statsd/src/StatsPullerManager.h
new file mode 100644
index 0000000..ab36df5
--- /dev/null
+++ b/cmds/statsd/src/StatsPullerManager.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef STATSD_STATSPULLERMANAGER_H
+#define STATSD_STATSPULLERMANAGER_H
+
+#include <utils/String16.h>
+#include <unordered_map>
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+const static int KERNEL_WAKELOCKS = 1;
+
+class StatsPullerManager {
+public:
+    // Enums of pulled data types (pullCodes)
+    // These values must be kept in sync with com/android/server/stats/StatsCompanionService.java.
+    // TODO: pull the constant from stats_events.proto instead
+    const static int KERNEL_WAKELOCKS;
+    StatsPullerManager();
+
+    String16 pull(const int pullCode);
+
+private:
+    std::unordered_map<int, std::unique_ptr<StatsPuller>> mStatsPullers;
+};
+
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+
+#endif  // STATSD_STATSPULLERMANAGER_H
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index ae7d66b..b496404 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -40,7 +40,8 @@
 namespace statsd {
 
 StatsService::StatsService(const sp<Looper>& handlerLooper)
-    : mAnomalyMonitor(new AnomalyMonitor(2))  // TODO: Change this based on the config
+    :   mAnomalyMonitor(new AnomalyMonitor(2)),m_UidMap(new UidMap()), mStatsPullerManager()
+    // TODO: Change AnomalyMonitor initialization based on the config
 {
     ALOGD("stats service constructed");
 }
@@ -131,6 +132,9 @@
         if (!args[0].compare(String8("config"))) {
             return doLoadConfig(in);
         }
+        if (!args[0].compare(String8("print-uid-map"))) {
+            return doPrintUidMap(out);
+        }
     }
 
     printCmdHelp(out);
@@ -153,6 +157,43 @@
     }
 }
 
+Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int32_t>& version,
+                                      const vector<String16>& app) {
+    if (DEBUG) ALOGD("StatsService::informAllUidData was called");
+
+    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
+        return Status::fromExceptionCode(Status::EX_SECURITY,
+                                         "Only system uid can call informAllUidData");
+    }
+
+    m_UidMap->updateMap(uid, version, app);
+    if (DEBUG) ALOGD("StatsService::informAllUidData succeeded");
+
+    return Status::ok();
+}
+
+Status StatsService::informOnePackage(const String16& app, int32_t uid, int32_t version) {
+    if (DEBUG) ALOGD("StatsService::informOnePackage was called");
+
+    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
+        return Status::fromExceptionCode(Status::EX_SECURITY,
+                                         "Only system uid can call informOnePackage");
+    }
+    m_UidMap->updateApp(app, uid, version);
+    return Status::ok();
+}
+
+Status StatsService::informOnePackageRemoved(const String16& app, int32_t uid) {
+    if (DEBUG) ALOGD("StatsService::informOnePackageRemoved was called");
+
+    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
+        return Status::fromExceptionCode(Status::EX_SECURITY,
+                                         "Only system uid can call informOnePackageRemoved");
+    }
+    m_UidMap->removeApp(app, uid);
+    return Status::ok();
+}
+
 Status StatsService::informAnomalyAlarmFired() {
     if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired was called");
 
@@ -177,9 +218,10 @@
 
     if (DEBUG) ALOGD("StatsService::informPollAlarmFired succeeded");
     // TODO: determine what services to poll and poll (or ask StatsCompanionService to poll) them.
-    String16 output = StatsPuller::pull(StatsPuller::PULL_CODE_KERNEL_WAKELOCKS);
+    String16 output = mStatsPullerManager.pull(StatsPullerManager::KERNEL_WAKELOCKS);
     // TODO: do something useful with the output instead of writing a string to screen.
     ALOGD("%s", String8(output).string());
+    ALOGD("%d", int(output.size()));
 
     return Status::ok();
 }
@@ -260,9 +302,15 @@
     return DropboxReader::readStatsLogs(out, args[1].string(), msec);
 }
 
+status_t StatsService::doPrintUidMap(FILE* out) {
+    m_UidMap->printUidMap(out);
+    return NO_ERROR;
+}
+
 void StatsService::printCmdHelp(FILE* out) {
     fprintf(out, "Usage:\n");
     fprintf(out, "\t print-stats-log [tag_required] [timestamp_nsec_optional]\n");
+    fprintf(out, "\t print-uid-map Prints the UID, app name, version mapping.\n");
     fprintf(out,
             "\t config\t Loads a new config from command-line (must be proto in wire-encoded "
             "format).\n");
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index a16b115..541f7e8 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -19,7 +19,9 @@
 
 #include "AnomalyMonitor.h"
 #include "StatsLogProcessor.h"
+#include "StatsPullerManager.h"
 #include "StatsPuller.h"
+#include "UidMap.h"
 
 #include <android/os/BnStatsManager.h>
 #include <android/os/IStatsCompanionService.h>
@@ -60,6 +62,11 @@
 
     virtual Status informPollAlarmFired();
 
+    virtual Status informAllUidData(const vector<int32_t>& uid, const vector<int32_t>& version,
+                                    const vector<String16>& app);
+    virtual Status informOnePackage(const String16& app, int32_t uid, int32_t version);
+    virtual Status informOnePackageRemoved(const String16& app, int32_t uid);
+
     virtual status_t setProcessor(const sp<StatsLogProcessor>& main_processor);
 
     // TODO: public for testing since statsd doesn't run when system starts. Change to private
@@ -71,10 +78,16 @@
     // TODO: Should be private. Temporarily public for testing purposes only.
     const sp<AnomalyMonitor> mAnomalyMonitor;
 
+    sp<UidMap> getUidMap() {
+        return m_UidMap;
+    }
+
     /** Fetches and returns the StatsCompanionService. */
     static sp<IStatsCompanionService> getStatsCompanionService();
 
- private:
+private:
+    sp<UidMap> m_UidMap; // Reference to the UID map needed for translating UID to app name/version.
+
     sp<StatsLogProcessor> m_processor;  // Reference to the processor for updating configs.
 
     status_t doPrintStatsLog(FILE* out, const Vector<String8>& args);
@@ -82,6 +95,10 @@
     void printCmdHelp(FILE* out);
 
     status_t doLoadConfig(FILE* in);
+
+    StatsPullerManager mStatsPullerManager;
+
+    status_t doPrintUidMap(FILE* out);
 };
 
 // --- StatsdDeathRecipient ---
diff --git a/cmds/statsd/src/UidMap.cpp b/cmds/statsd/src/UidMap.cpp
new file mode 100644
index 0000000..76a7f3f
--- /dev/null
+++ b/cmds/statsd/src/UidMap.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, versionCode 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.
+ */
+
+#include "UidMap.h"
+#include <cutils/log.h>
+#include <utils/Errors.h>
+
+using namespace android;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+bool UidMap::hasApp(int uid, const string& packageName) const {
+    lock_guard<mutex> lock(mMutex);
+
+    auto range = mMap.equal_range(uid);
+    for (auto it = range.first; it != range.second; ++it) {
+        if (it->second.packageName == packageName) {
+            return true;
+        }
+    }
+    return false;
+}
+
+int UidMap::getAppVersion(int uid, const string& packageName) const {
+    lock_guard<mutex> lock(mMutex);
+
+    auto range = mMap.equal_range(uid);
+    for (auto it = range.first; it != range.second; ++it) {
+        if (it->second.packageName == packageName) {
+            return it->second.versionCode;
+        }
+    }
+    return 0;
+}
+
+void UidMap::updateMap(const vector <int32_t> &uid, const vector <int32_t> &versionCode,
+                       const vector <String16> &packageName) {
+    lock_guard<mutex> lock(mMutex); // Exclusively lock for updates.
+
+    mMap.clear();
+    for (unsigned long j=0; j<uid.size(); j++) {
+        mMap.insert(make_pair(uid[j], AppData(string(String8(packageName[j]).string()),
+                                              versionCode[j])));
+    }
+
+    if (mOutput.initial_size() == 0) { // Provide the initial states in the mOutput proto
+        for (unsigned long j=0; j<uid.size(); j++) {
+            auto t = mOutput.add_initial();
+            t->set_app(string(String8(packageName[j]).string()));
+            t->set_version(int(versionCode[j]));
+            t->set_uid(uid[j]);
+        }
+    }
+}
+
+void UidMap::updateApp(const String16& app_16, const int32_t& uid, const int32_t& versionCode){
+    lock_guard<mutex> lock(mMutex);
+
+    string app = string(String8(app_16).string());
+
+    // Notify any interested producers that this app has updated
+    for (auto it : mSubscribers) {
+        it->notifyAppUpgrade(app, uid, versionCode);
+    }
+
+    auto log = mOutput.add_changes();
+    log->set_deletion(false);
+    //log.timestamp = TODO: choose how timestamps are computed
+    log->set_app(app);
+    log->set_uid(uid);
+    log->set_version(versionCode);
+
+    auto range = mMap.equal_range(int(uid));
+    for (auto it = range.first; it != range.second; ++it) {
+        if (it->second.packageName == app) {
+            it->second.versionCode = int(versionCode);
+            return;
+        }
+        ALOGD("updateApp failed to find the app %s with uid %i to update", app.c_str(), uid);
+        return;
+    }
+
+    // Otherwise, we need to add an app at this uid.
+    mMap.insert(make_pair(uid, AppData(app, int(versionCode))));
+}
+
+
+void UidMap::removeApp(const String16& app_16, const int32_t& uid){
+    lock_guard<mutex> lock(mMutex);
+
+    string app = string(String8(app_16).string());
+
+    auto log = mOutput.add_changes();
+    log->set_deletion(true);
+    //log.timestamp = TODO: choose how timestamps are computed
+    log->set_app(app);
+    log->set_uid(uid);
+
+    auto range = mMap.equal_range(int(uid));
+    for (auto it = range.first; it != range.second; ++it) {
+        if (it->second.packageName == app) {
+            mMap.erase(it);
+            return;
+        }
+    }
+    ALOGD("removeApp failed to find the app %s with uid %i to remove", app.c_str(), uid);
+    return;
+}
+
+void UidMap::addListener(sp<PackageInfoListener> producer) {
+    lock_guard<mutex> lock(mMutex); // Lock for updates
+    mSubscribers.insert(producer);
+}
+
+void UidMap::removeListener(sp<PackageInfoListener> producer) {
+    lock_guard<mutex> lock(mMutex); // Lock for updates
+    mSubscribers.erase(producer);
+}
+
+UidMapping UidMap::getAndClearOutput() {
+    lock_guard<mutex> lock(mMutex); // Lock for updates
+
+    auto ret = UidMapping(mOutput); // Copy that will be returned.
+    mOutput.Clear();
+
+    // Re-initialize the initial state for the outputs. This results in extra data being uploaded
+    // but helps ensure we can't re-construct the UID->app name, versionCode mapping in server.
+    for (auto it : mMap) {
+        auto t = mOutput.add_initial();
+        t->set_app(it.second.packageName);
+        t->set_version(it.second.versionCode);
+        t->set_uid(it.first);
+    }
+
+    return ret;
+}
+
+void UidMap::printUidMap(FILE* out) {
+    lock_guard<mutex> lock(mMutex);
+
+    for (auto it : mMap) {
+        fprintf(out, "%s, v%d (%i)\n", it.second.packageName.c_str(), it.second.versionCode, it.first);
+    }
+}
+
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/UidMap.h b/cmds/statsd/src/UidMap.h
new file mode 100644
index 0000000..1481010
--- /dev/null
+++ b/cmds/statsd/src/UidMap.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef STATSD_UIDMAP_H
+#define STATSD_UIDMAP_H
+
+#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "PackageInfoListener.h"
+
+#include <binder/IResultReceiver.h>
+#include <binder/IShellCallback.h>
+#include <log/logprint.h>
+#include <mutex>
+#include <string>
+#include <stdio.h>
+#include <set>
+#include <unordered_map>
+#include <utils/RefBase.h>
+
+using namespace std;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+struct AppData {
+    const string packageName;
+    int versionCode;
+
+    AppData(const string& a, const int v) : packageName(a), versionCode(v) {};
+};
+
+// UidMap keeps track of what the corresponding app name (APK name) and version code for every uid
+// at any given moment. This map must be updated by StatsCompanionService.
+class UidMap : public virtual android::RefBase  {
+public:
+    /*
+     * All three inputs must be the same size, and the jth element in each array refers to the same
+     * tuple, ie. uid[j] corresponds to packageName[j] with versionCode[j].
+     */
+    void updateMap(const vector<int32_t>& uid, const vector<int32_t>& versionCode,
+                   const vector<String16>& packageName);
+
+    // Returns true if the given uid contains the specified app (eg. com.google.android.gms).
+    bool hasApp(int uid, const string& packageName) const;
+
+    int getAppVersion(int uid, const string& packageName) const;
+
+    void updateApp(const String16& packageName, const int32_t& uid, const int32_t& versionCode);
+    void removeApp(const String16& packageName, const int32_t& uid);
+
+    // Helper for debugging contents of this uid map. Can be triggered with:
+    // adb shell cmd stats print-uid-map
+    void printUidMap(FILE* out);
+
+    // Commands for indicating to the map that a producer should be notified if an app is updated.
+    // This allows the metric producer to distinguish when the same uid or app represents a
+    // different version of an app.
+    void addListener(sp<PackageInfoListener> producer);
+    // Remove the listener from the set of metric producers that subscribe to updates.
+    void removeListener(sp<PackageInfoListener> producer);
+
+    // Grabs the current output contents and then clears it.
+    UidMapping getAndClearOutput();
+
+private:
+    // TODO: Use shared_mutex for improved read-locking if a library can be found in Android.
+    mutable mutex mMutex;
+
+    std::unordered_multimap<int, AppData> mMap;
+
+    // We prepare the output proto as apps are updated, so that we can grab the current output.
+    UidMapping mOutput;
+
+    // Metric producers that should be notified if there's an upgrade in any app.
+    set<sp<PackageInfoListener>> mSubscribers;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+
+#endif //STATSD_UIDMAP_H
+
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
new file mode 100644
index 0000000..6188383
--- /dev/null
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+#define LOG_TAG "CombinationConditionTracker"
+#define DEBUG true  // STOPSHIP if true
+#define VLOG(...) \
+    if (DEBUG) ALOGD(__VA_ARGS__);
+
+#include "CombinationConditionTracker.h"
+#include <cutils/log.h>
+#include <log/logprint.h>
+using std::string;
+using std::unique_ptr;
+using std::unordered_map;
+using std::vector;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+CombinationConditionTracker::CombinationConditionTracker(const string& name, const int index)
+    : ConditionTracker(name, index) {
+    VLOG("creating CombinationConditionTracker %s", mName.c_str());
+}
+
+CombinationConditionTracker::~CombinationConditionTracker() {
+    VLOG("~CombinationConditionTracker() %s", mName.c_str());
+}
+
+bool CombinationConditionTracker::init(const vector<Condition>& allConditionConfig,
+                                       const vector<sp<ConditionTracker>>& allConditionTrackers,
+                                       const unordered_map<string, int>& conditionNameIndexMap,
+                                       vector<bool>& stack) {
+    VLOG("Combiniation condition init() %s", mName.c_str());
+    if (mInitialized) {
+        return true;
+    }
+
+    // mark this node as visited in the recursion stack.
+    stack[mIndex] = true;
+
+    Condition_Combination combinationCondition = allConditionConfig[mIndex].combination();
+
+    if (!combinationCondition.has_operation()) {
+        return false;
+    }
+    mLogicalOperation = combinationCondition.operation();
+
+    if (mLogicalOperation == LogicalOperation::NOT && combinationCondition.condition_size() != 1) {
+        return false;
+    }
+
+    for (string child : combinationCondition.condition()) {
+        auto it = conditionNameIndexMap.find(child);
+
+        if (it == conditionNameIndexMap.end()) {
+            ALOGW("Condition %s not found in the config", child.c_str());
+            return false;
+        }
+
+        int childIndex = it->second;
+        const auto& childTracker = allConditionTrackers[childIndex];
+        // if the child is a visited node in the recursion -> circle detected.
+        if (stack[childIndex]) {
+            ALOGW("Circle detected!!!");
+            return false;
+        }
+
+        bool initChildSucceeded = childTracker->init(allConditionConfig, allConditionTrackers,
+                                                     conditionNameIndexMap, stack);
+
+        if (!initChildSucceeded) {
+            ALOGW("Child initialization failed %s ", child.c_str());
+            return false;
+        } else {
+            ALOGW("Child initialization success %s ", child.c_str());
+        }
+
+        mChildren.push_back(childIndex);
+
+        mTrackerIndex.insert(childTracker->getLogTrackerIndex().begin(),
+                             childTracker->getLogTrackerIndex().end());
+    }
+
+    // unmark this node in the recursion stack.
+    stack[mIndex] = false;
+
+    mInitialized = true;
+
+    return true;
+}
+
+bool CombinationConditionTracker::evaluateCondition(
+        const LogEventWrapper& event, const std::vector<MatchingState>& eventMatcherValues,
+        const std::vector<sp<ConditionTracker>>& mAllConditions,
+        std::vector<ConditionState>& conditionCache, std::vector<bool>& changedCache) {
+    // value is up to date.
+    if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
+        return false;
+    }
+
+    for (const int childIndex : mChildren) {
+        if (conditionCache[childIndex] == ConditionState::kNotEvaluated) {
+            const sp<ConditionTracker>& child = mAllConditions[childIndex];
+            child->evaluateCondition(event, eventMatcherValues, mAllConditions, conditionCache,
+                                     changedCache);
+        }
+    }
+
+    ConditionState newCondition =
+            evaluateCombinationCondition(mChildren, mLogicalOperation, conditionCache);
+
+    bool changed = (mConditionState != newCondition);
+    mConditionState = newCondition;
+
+    conditionCache[mIndex] = mConditionState;
+
+    changedCache[mIndex] = changed;
+    return changed;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h
new file mode 100644
index 0000000..38780e7
--- /dev/null
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef COMBINATION_CONDITION_TRACKER_H
+#define COMBINATION_CONDITION_TRACKER_H
+
+#include "ConditionTracker.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class CombinationConditionTracker : public virtual ConditionTracker {
+public:
+    CombinationConditionTracker(const std::string& name, const int index);
+
+    ~CombinationConditionTracker();
+
+    bool init(const std::vector<Condition>& allConditionConfig,
+              const std::vector<sp<ConditionTracker>>& allConditionTrackers,
+              const std::unordered_map<std::string, int>& conditionNameIndexMap,
+              std::vector<bool>& stack) override;
+
+    bool evaluateCondition(const LogEventWrapper& event,
+                           const std::vector<MatchingState>& eventMatcherValues,
+                           const std::vector<sp<ConditionTracker>>& mAllConditions,
+                           std::vector<ConditionState>& conditionCache,
+                           std::vector<bool>& changedCache) override;
+
+private:
+    LogicalOperation mLogicalOperation;
+    // Store index of the children Conditions.
+    // We don't store string name of the Children, because we want to get rid of the hash map to
+    // map the name to object. We don't want to store smart pointers to children, because it
+    // increases the risk of circular dependency and memory leak.
+    std::vector<int> mChildren;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+
+#endif  // COMBINATION_CONDITION_TRACKER_H
diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h
new file mode 100644
index 0000000..2da8fa0
--- /dev/null
+++ b/cmds/statsd/src/condition/ConditionTracker.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef CONDITION_TRACKER_H
+#define CONDITION_TRACKER_H
+
+#include <cutils/log.h>
+#include <log/logprint.h>
+#include <utils/RefBase.h>
+#include <unordered_map>
+#include "../matchers/LogMatchingTracker.h"
+#include "../matchers/matcher_util.h"
+#include "condition_util.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class ConditionTracker : public virtual RefBase {
+public:
+    ConditionTracker(const std::string& name, const int index)
+        : mName(name),
+          mIndex(index),
+          mInitialized(false),
+          mConditionState(ConditionState::kUnknown),
+          mTrackerIndex(){};
+
+    virtual ~ConditionTracker(){};
+
+    // Initialize this ConditionTracker. This initialization is done recursively (DFS). It can also
+    // be done in the constructor, but we do it separately because (1) easy to return a bool to
+    // indicate whether the initialization is successful. (2) makes unit test easier.
+    // allConditionConfig: the list of all Condition config from statsd_config.
+    // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
+    //                       need to call init() on children conditions)
+    // conditionNameIndexMap: the mapping from condition name to its index.
+    // stack: a bit map to keep track which nodes have been visited on the stack in the recursion.
+    virtual bool init(const std::vector<Condition>& allConditionConfig,
+                      const std::vector<sp<ConditionTracker>>& allConditionTrackers,
+                      const std::unordered_map<std::string, int>& conditionNameIndexMap,
+                      std::vector<bool>& stack) = 0;
+
+    // evaluate current condition given the new event.
+    // return true if the condition state changed, false if the condition state is not changed.
+    // event: the new log event
+    // eventMatcherValues: the results of the LogMatcherTrackers. LogMatcherTrackers always process
+    //                     event before ConditionTrackers, because ConditionTracker depends on
+    //                     LogMatchingTrackers.
+    // mAllConditions: the list of all ConditionTracker
+    // conditionCache: the cached results of the ConditionTrackers for this new event.
+    // changedCache: the bit map to record whether the condition has changed.
+    virtual bool evaluateCondition(const LogEventWrapper& event,
+                                   const std::vector<MatchingState>& eventMatcherValues,
+                                   const std::vector<sp<ConditionTracker>>& mAllConditions,
+                                   std::vector<ConditionState>& conditionCache,
+                                   std::vector<bool>& changedCache) = 0;
+
+    // Return the current condition state.
+    virtual ConditionState isConditionMet() {
+        ALOGW("Condition %s value %d", mName.c_str(), mConditionState);
+        return mConditionState;
+    };
+
+    // return the list of LogMatchingTracker index that this ConditionTracker uses.
+    virtual const std::set<int>& getLogTrackerIndex() const {
+        return mTrackerIndex;
+    }
+
+protected:
+    // We don't really need the string name, but having a name here makes log messages
+    // easy to debug.
+    const std::string mName;
+
+    // the index of this condition in the manager's condition list.
+    const int mIndex;
+
+    // if it's properly initialized.
+    bool mInitialized;
+
+    // current condition state.
+    ConditionState mConditionState;
+
+    // the list of LogMatchingTracker index that this ConditionTracker uses.
+    std::set<int> mTrackerIndex;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+
+#endif  // CONDITION_TRACKER_H
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
new file mode 100644
index 0000000..e78c0de
--- /dev/null
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "Stats_SimpleConditionTracker"
+#define DEBUG true  // STOPSHIP if true
+#define VLOG(...) \
+    if (DEBUG) ALOGD(__VA_ARGS__);
+
+#include "SimpleConditionTracker.h"
+#include <cutils/log.h>
+#include <log/logprint.h>
+
+using std::string;
+using std::unique_ptr;
+using std::unordered_map;
+using std::vector;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+SimpleConditionTracker::SimpleConditionTracker(
+        const string& name, const int index, const SimpleCondition& simpleCondition,
+        const unordered_map<string, int>& trackerNameIndexMap)
+    : ConditionTracker(name, index) {
+    VLOG("creating SimpleConditionTracker %s", mName.c_str());
+    mCountNesting = simpleCondition.count_nesting();
+
+    if (simpleCondition.has_start()) {
+        auto pair = trackerNameIndexMap.find(simpleCondition.start());
+        if (pair == trackerNameIndexMap.end()) {
+            ALOGW("Start matcher %s not found in the config", simpleCondition.start().c_str());
+            return;
+        }
+        mStartLogMatcherIndex = pair->second;
+        mTrackerIndex.insert(mStartLogMatcherIndex);
+    } else {
+        mStartLogMatcherIndex = -1;
+    }
+
+    if (simpleCondition.has_stop()) {
+        auto pair = trackerNameIndexMap.find(simpleCondition.stop());
+        if (pair == trackerNameIndexMap.end()) {
+            ALOGW("Stop matcher %s not found in the config", simpleCondition.stop().c_str());
+            return;
+        }
+        mStopLogMatcherIndex = pair->second;
+        mTrackerIndex.insert(mStopLogMatcherIndex);
+    } else {
+        mStopLogMatcherIndex = -1;
+    }
+
+    if (simpleCondition.has_stop_all()) {
+        auto pair = trackerNameIndexMap.find(simpleCondition.stop_all());
+        if (pair == trackerNameIndexMap.end()) {
+            ALOGW("Stop matcher %s not found in the config", simpleCondition.stop().c_str());
+            return;
+        }
+        mStopAllLogMatcherIndex = pair->second;
+        mTrackerIndex.insert(mStopAllLogMatcherIndex);
+    } else {
+        mStopAllLogMatcherIndex = -1;
+    }
+
+    mInitialized = true;
+}
+
+SimpleConditionTracker::~SimpleConditionTracker() {
+    VLOG("~SimpleConditionTracker()");
+}
+
+bool SimpleConditionTracker::init(const vector<Condition>& allConditionConfig,
+                                  const vector<sp<ConditionTracker>>& allConditionTrackers,
+                                  const unordered_map<string, int>& conditionNameIndexMap,
+                                  vector<bool>& stack) {
+    // SimpleConditionTracker does not have dependency on other conditions, thus we just return
+    // if the initialization was successful.
+    return mInitialized;
+}
+
+bool SimpleConditionTracker::evaluateCondition(const LogEventWrapper& event,
+                                               const vector<MatchingState>& eventMatcherValues,
+                                               const vector<sp<ConditionTracker>>& mAllConditions,
+                                               vector<ConditionState>& conditionCache,
+                                               vector<bool>& changedCache) {
+    if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
+        // it has been evaluated.
+        VLOG("Yes, already evaluated, %s %d", mName.c_str(), mConditionState);
+        return false;
+    }
+
+    // Ignore nesting, because we know we cannot trust ourselves on tracking nesting conditions.
+    ConditionState newCondition = mConditionState;
+    // Note: The order to evaluate the following start, stop, stop_all matters.
+    // The priority of overwrite is stop_all > stop > start.
+    if (mStartLogMatcherIndex >= 0 &&
+        eventMatcherValues[mStartLogMatcherIndex] == MatchingState::kMatched) {
+        newCondition = ConditionState::kTrue;
+    }
+
+    if (mStopLogMatcherIndex >= 0 &&
+        eventMatcherValues[mStopLogMatcherIndex] == MatchingState::kMatched) {
+        newCondition = ConditionState::kFalse;
+    }
+
+    if (mStopAllLogMatcherIndex >= 0 &&
+        eventMatcherValues[mStopAllLogMatcherIndex] == MatchingState::kMatched) {
+        newCondition = ConditionState::kFalse;
+    }
+
+    bool changed = (mConditionState != newCondition);
+    mConditionState = newCondition;
+    conditionCache[mIndex] = mConditionState;
+    changedCache[mIndex] = changed;
+    return changed;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h
new file mode 100644
index 0000000..41e1707
--- /dev/null
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SIMPLE_CONDITION_TRACKER_H
+#define SIMPLE_CONDITION_TRACKER_H
+
+#include "ConditionTracker.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class SimpleConditionTracker : public virtual ConditionTracker {
+public:
+    SimpleConditionTracker(const std::string& name, const int index,
+                           const SimpleCondition& simpleCondition,
+                           const std::unordered_map<std::string, int>& trackerNameIndexMap);
+
+    ~SimpleConditionTracker();
+
+    bool init(const std::vector<Condition>& allConditionConfig,
+              const std::vector<sp<ConditionTracker>>& allConditionTrackers,
+              const std::unordered_map<std::string, int>& conditionNameIndexMap,
+              std::vector<bool>& stack) override;
+
+    bool evaluateCondition(const LogEventWrapper& event,
+                           const std::vector<MatchingState>& eventMatcherValues,
+                           const std::vector<sp<ConditionTracker>>& mAllConditions,
+                           std::vector<ConditionState>& conditionCache,
+                           std::vector<bool>& changedCache) override;
+
+private:
+    // The index of the LogEventMatcher which defines the start.
+    int mStartLogMatcherIndex;
+
+    // The index of the LogEventMatcher which defines the end.
+    int mStopLogMatcherIndex;
+
+    // if the start end needs to be nested.
+    bool mCountNesting;
+
+    // The index of the LogEventMatcher which defines the stop all.
+    int mStopAllLogMatcherIndex;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+
+#endif  // SIMPLE_CONDITION_TRACKER_H
diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp
new file mode 100644
index 0000000..cb07d15
--- /dev/null
+++ b/cmds/statsd/src/condition/condition_util.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "condition_util.h"
+
+#include <cutils/log.h>
+#include <log/event_tag_map.h>
+#include <log/log_event_list.h>
+#include <log/logprint.h>
+#include <utils/Errors.h>
+#include <unordered_map>
+#include "ConditionTracker.h"
+#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+#include "stats_util.h"
+
+using std::set;
+using std::string;
+using std::unordered_map;
+using std::vector;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+ConditionState evaluateCombinationCondition(const std::vector<int>& children,
+                                            const LogicalOperation& operation,
+                                            const std::vector<ConditionState>& conditionCache) {
+    ConditionState newCondition;
+
+    bool hasUnknown = false;
+    bool hasFalse = false;
+    bool hasTrue = false;
+
+    for (auto childIndex : children) {
+        ConditionState childState = conditionCache[childIndex];
+        if (childState == ConditionState::kUnknown) {
+            hasUnknown = true;
+            break;
+        }
+        if (childState == ConditionState::kFalse) {
+            hasFalse = true;
+        }
+        if (childState == ConditionState::kTrue) {
+            hasTrue = true;
+        }
+    }
+
+    // If any child condition is in unknown state, the condition is unknown too.
+    if (hasUnknown) {
+        return ConditionState::kUnknown;
+    }
+
+    switch (operation) {
+        case LogicalOperation::AND: {
+            newCondition = hasFalse ? ConditionState::kFalse : ConditionState::kTrue;
+            break;
+        }
+        case LogicalOperation::OR: {
+            newCondition = hasTrue ? ConditionState::kTrue : ConditionState::kFalse;
+            break;
+        }
+        case LogicalOperation::NOT:
+            newCondition = (conditionCache[children[0]] == ConditionState::kFalse)
+                                   ? ConditionState::kTrue
+                                   : ConditionState::kFalse;
+            break;
+        case LogicalOperation::NAND:
+            newCondition = hasFalse ? ConditionState::kTrue : ConditionState::kFalse;
+            break;
+        case LogicalOperation::NOR:
+            newCondition = hasTrue ? ConditionState::kFalse : ConditionState::kTrue;
+            break;
+    }
+    return newCondition;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/metrics/ConditionTracker.h b/cmds/statsd/src/condition/condition_util.h
similarity index 60%
rename from cmds/statsd/src/metrics/ConditionTracker.h
rename to cmds/statsd/src/condition/condition_util.h
index b94d5ab..a4fcea3 100644
--- a/cmds/statsd/src/metrics/ConditionTracker.h
+++ b/cmds/statsd/src/condition/condition_util.h
@@ -14,38 +14,28 @@
  * limitations under the License.
  */
 
-#ifndef CONDITION_TRACKER_H
-#define CONDITION_TRACKER_H
+#ifndef CONDITION_UTIL_H
+#define CONDITION_UTIL_H
 
-#include <utils/RefBase.h>
-#include "../matchers/LogEntryMatcherManager.h"
+#include <vector>
+#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 
 namespace android {
 namespace os {
 namespace statsd {
 
-class ConditionTracker : public RefBase {
-public:
-    ConditionTracker();
-
-    ConditionTracker(const Condition& condition);
-
-    ~ConditionTracker();
-
-    void evaluateCondition(const LogEventWrapper& event);
-
-    bool isConditionMet() const;
-
-private:
-    // this is the definition of the Condition.
-    Condition mCondition;
-
-    bool mIsConditionMet;
+enum ConditionState {
+    kNotEvaluated = -2,
+    kUnknown = -1,
+    kFalse = 0,
+    kTrue = 1,
 };
 
+ConditionState evaluateCombinationCondition(const std::vector<int>& children,
+                                            const LogicalOperation& operation,
+                                            const std::vector<ConditionState>& conditionCache);
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
-
-#endif  // CONDITION_TRACKER_H
+#endif  // CONDITION_UTIL_H
diff --git a/cmds/statsd/src/indexed_priority_queue.h b/cmds/statsd/src/indexed_priority_queue.h
index c749c3e..81e8b3d 100644
--- a/cmds/statsd/src/indexed_priority_queue.h
+++ b/cmds/statsd/src/indexed_priority_queue.h
@@ -55,6 +55,8 @@
     void push(sp<const AA> a);
     /** Removes a from the priority queue. If not present or a==nullptr, does nothing. */
     void remove(sp<const AA> a);
+    /** Removes the top element, if there is one. */
+    void pop();
     /** Removes all elements. */
     void clear();
     /** Returns whether priority queue contains a (not just a copy of a, but a itself). */
@@ -127,6 +129,28 @@
     sift_down(idx);
 }
 
+// The same as, but slightly more efficient than, remove(top()).
+template <class AA, class Comparator>
+void indexed_priority_queue<AA, Comparator>::pop() {
+  sp<const AA> a = top();
+  if (a == nullptr) return;
+  const size_t idx = 1;
+  if (idx == size()) {  // if a is the last element
+    pq.pop_back();
+    indices.erase(a);
+    return;
+  }
+  // move last element (guaranteed not to be at idx) to idx, then delete a
+  sp<const AA> last_a = pq.back();
+  pq[idx] = last_a;
+  pq.pop_back();
+  indices[last_a] = idx;
+  indices.erase(a);
+
+  // get the heap back in order (since the element at idx is not in order)
+  sift_down(idx);
+}
+
 template <class AA, class Comparator>
 void indexed_priority_queue<AA, Comparator>::clear() {
     pq.clear();
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index b303321..37477dc 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -20,6 +20,7 @@
 #include "LogReader.h"
 #include "StatsLogProcessor.h"
 #include "StatsService.h"
+#include "UidMap.h"
 
 #include <binder/IInterface.h>
 #include <binder/IPCThreadState.h>
@@ -56,7 +57,7 @@
 
     // Put the printer one first, so it will print before the real ones.
     reader->AddListener(new LogEntryPrinter(STDOUT_FILENO));
-    sp<StatsLogProcessor> main_processor = new StatsLogProcessor();
+    sp<StatsLogProcessor> main_processor = new StatsLogProcessor(data->service->getUidMap());
     data->service->setProcessor(main_processor);
     reader->AddListener(main_processor);
 
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
new file mode 100644
index 0000000..9f9b648
--- /dev/null
+++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "CombinationLogMatchingTracker.h"
+
+#include <cutils/log.h>
+#include "matcher_util.h"
+using std::set;
+using std::string;
+using std::unique_ptr;
+using std::unordered_map;
+using std::vector;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+CombinationLogMatchingTracker::CombinationLogMatchingTracker(const string& name, const int index)
+    : LogMatchingTracker(name, index) {
+}
+
+CombinationLogMatchingTracker::~CombinationLogMatchingTracker() {
+}
+
+bool CombinationLogMatchingTracker::init(const vector<LogEntryMatcher>& allLogMatchers,
+                                         const vector<sp<LogMatchingTracker>>& allTrackers,
+                                         const unordered_map<string, int>& matcherMap,
+                                         vector<bool>& stack) {
+    if (mInitialized) {
+        return true;
+    }
+
+    // mark this node as visited in the recursion stack.
+    stack[mIndex] = true;
+
+    LogEntryMatcher_Combination matcher = allLogMatchers[mIndex].combination();
+
+    // LogicalOperation is missing in the config
+    if (!matcher.has_operation()) {
+        return false;
+    }
+
+    mLogicalOperation = matcher.operation();
+
+    if (mLogicalOperation == LogicalOperation::NOT && matcher.matcher_size() != 1) {
+        return false;
+    }
+
+    for (const string& child : matcher.matcher()) {
+        auto pair = matcherMap.find(child);
+        if (pair == matcherMap.end()) {
+            ALOGW("Matcher %s not found in the config", child.c_str());
+            return false;
+        }
+
+        int childIndex = pair->second;
+
+        // if the child is a visited node in the recursion -> circle detected.
+        if (stack[childIndex]) {
+            ALOGE("Circle detected in matcher config");
+            return false;
+        }
+
+        if (!allTrackers[childIndex]->init(allLogMatchers, allTrackers, matcherMap, stack)) {
+            ALOGW("child matcher init failed %s", child.c_str());
+            return false;
+        }
+
+        mChildren.push_back(childIndex);
+
+        const set<int>& childTagIds = allTrackers[childIndex]->getTagIds();
+        mTagIds.insert(childTagIds.begin(), childTagIds.end());
+    }
+
+    mInitialized = true;
+    // unmark this node in the recursion stack.
+    stack[mIndex] = false;
+    return true;
+}
+
+void CombinationLogMatchingTracker::onLogEvent(const LogEventWrapper& event,
+                                               const vector<sp<LogMatchingTracker>>& allTrackers,
+                                               vector<MatchingState>& matcherResults) {
+    // this event has been processed.
+    if (matcherResults[mIndex] != MatchingState::kNotComputed) {
+        return;
+    }
+
+    if (mTagIds.find(event.tagId) == mTagIds.end()) {
+        matcherResults[mIndex] = MatchingState::kNotMatched;
+        return;
+    }
+
+    // evaluate children matchers if they haven't been evaluated.
+    for (const int childIndex : mChildren) {
+        if (matcherResults[childIndex] == MatchingState::kNotComputed) {
+            const sp<LogMatchingTracker>& child = allTrackers[childIndex];
+            child->onLogEvent(event, allTrackers, matcherResults);
+        }
+    }
+
+    bool matched = combinationMatch(mChildren, mLogicalOperation, matcherResults);
+    matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
new file mode 100644
index 0000000..51ee232
--- /dev/null
+++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+#ifndef COMBINATION_LOG_MATCHING_TRACKER_H
+#define COMBINATION_LOG_MATCHING_TRACKER_H
+
+#include <log/log_read.h>
+#include <log/logprint.h>
+#include <set>
+#include <unordered_map>
+#include <vector>
+#include "LogMatchingTracker.h"
+#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+// Represents a LogEntryMatcher_Combination in the StatsdConfig.
+class CombinationLogMatchingTracker : public virtual LogMatchingTracker {
+public:
+    CombinationLogMatchingTracker(const std::string& name, const int index);
+
+    bool init(const std::vector<LogEntryMatcher>& allLogMatchers,
+              const std::vector<sp<LogMatchingTracker>>& allTrackers,
+              const std::unordered_map<std::string, int>& matcherMap,
+              std::vector<bool>& stack);
+
+    ~CombinationLogMatchingTracker();
+
+    void onLogEvent(const LogEventWrapper& event,
+                    const std::vector<sp<LogMatchingTracker>>& allTrackers,
+                    std::vector<MatchingState>& matcherResults) override;
+
+private:
+    LogicalOperation mLogicalOperation;
+
+    std::vector<int> mChildren;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+#endif  // COMBINATION_LOG_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/LogMatchingTracker.h b/cmds/statsd/src/matchers/LogMatchingTracker.h
new file mode 100644
index 0000000..4244bd5
--- /dev/null
+++ b/cmds/statsd/src/matchers/LogMatchingTracker.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef LOG_MATCHING_TRACKER_H
+#define LOG_MATCHING_TRACKER_H
+
+#include <log/log_read.h>
+#include <log/logprint.h>
+#include <utils/RefBase.h>
+#include <set>
+#include <unordered_map>
+
+#include <vector>
+#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+#include "matcher_util.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class LogMatchingTracker : public virtual RefBase {
+public:
+    LogMatchingTracker(const std::string& name, const int index)
+        : mName(name), mIndex(index), mInitialized(false){};
+
+    virtual ~LogMatchingTracker(){};
+
+    // Initialize this LogMatchingTracker.
+    // allLogMatchers: the list of the LogEntryMatcher proto config. This is needed because we don't
+    //                 store the proto object in memory. We only need it during initilization.
+    // allTrackers: the list of the LogMatchingTracker objects. It's a one-to-one mapping with
+    //              allLogMatchers. This is needed because the initialization is done recursively
+    //              for CombinationLogMatchingTrackers using DFS.
+    // stack: a bit map to record which matcher has been visited on the stack. This is for detecting
+    //        circle dependency.
+    virtual bool init(const std::vector<LogEntryMatcher>& allLogMatchers,
+                      const std::vector<sp<LogMatchingTracker>>& allTrackers,
+                      const std::unordered_map<std::string, int>& matcherMap,
+                      std::vector<bool>& stack) = 0;
+
+    // Called when a log event comes.
+    // event: the log event.
+    // allTrackers: the list of all LogMatchingTrackers. This is needed because the log processing
+    //              is done recursively.
+    // matcherResults: The cached results for all matchers for this event. Parent matchers can
+    //                 directly access the children's matching results if they have been evaluated.
+    //                 Otherwise, call children matchers' onLogEvent.
+    virtual void onLogEvent(const LogEventWrapper& event,
+                            const std::vector<sp<LogMatchingTracker>>& allTrackers,
+                            std::vector<MatchingState>& matcherResults) = 0;
+
+    // Get the tagIds that this matcher cares about. The combined collection is stored
+    // in MetricMananger, so that we can pass any LogEvents that are not interest of us. It uses
+    // some memory but hopefully it can save us much CPU time when there is flood of events.
+    virtual const std::set<int>& getTagIds() const {
+        return mTagIds;
+    }
+
+protected:
+    // Name of this matching. We don't really need the name, but it makes log message easy to debug.
+    const std::string mName;
+
+    // Index of this LogMatchingTracker in MetricsManager's container.
+    const int mIndex;
+
+    // Whether this LogMatchingTracker has been properly initialized.
+    bool mInitialized;
+
+    // The collection of the event tag ids that this LogMatchingTracker cares. So we can quickly
+    // return kNotMatched when we receive an event with an id not in the list. This is especially
+    // useful when we have a complex CombinationLogMatcherTracker.
+    // TODO: Consider use an array instead of stl set. In reality, the number of the tag ids a
+    // LogMatchingTracker cares is only a few.
+    std::set<int> mTagIds;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+
+#endif  // LOG_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
new file mode 100644
index 0000000..1c83039
--- /dev/null
+++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "SimpleLogMatchingTracker"
+#define DEBUG true  // STOPSHIP if true
+#define VLOG(...) \
+    if (DEBUG) ALOGD(__VA_ARGS__);
+
+#include "SimpleLogMatchingTracker.h"
+#include <cutils/log.h>
+#include <log/logprint.h>
+
+using std::string;
+using std::unique_ptr;
+using std::unordered_map;
+using std::vector;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+SimpleLogMatchingTracker::SimpleLogMatchingTracker(const string& name, const int index,
+                                                   const SimpleLogEntryMatcher& matcher)
+    : LogMatchingTracker(name, index), mMatcher(matcher) {
+    for (int i = 0; i < matcher.tag_size(); i++) {
+        mTagIds.insert(matcher.tag(i));
+    }
+    mInitialized = true;
+}
+
+SimpleLogMatchingTracker::~SimpleLogMatchingTracker() {
+}
+
+bool SimpleLogMatchingTracker::init(const vector<LogEntryMatcher>& allLogMatchers,
+                                    const vector<sp<LogMatchingTracker>>& allTrackers,
+                                    const unordered_map<string, int>& matcherMap,
+                                    vector<bool>& stack) {
+    // no need to do anything.
+    return true;
+}
+
+void SimpleLogMatchingTracker::onLogEvent(const LogEventWrapper& event,
+                                          const vector<sp<LogMatchingTracker>>& allTrackers,
+                                          vector<MatchingState>& matcherResults) {
+    if (matcherResults[mIndex] != MatchingState::kNotComputed) {
+        VLOG("Matcher %s already evaluated ", mName.c_str());
+        return;
+    }
+
+    if (mTagIds.find(event.tagId) == mTagIds.end()) {
+        matcherResults[mIndex] = MatchingState::kNotMatched;
+        return;
+    }
+
+    bool matched = matchesSimple(mMatcher, event);
+    matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched;
+    VLOG("Stats SimpleLogMatcher %s matched? %d", mName.c_str(), matched);
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
new file mode 100644
index 0000000..65dbe64
--- /dev/null
+++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SIMPLE_LOG_MATCHING_TRACKER_H
+#define SIMPLE_LOG_MATCHING_TRACKER_H
+
+#include <log/log_read.h>
+#include <log/logprint.h>
+#include <set>
+#include <unordered_map>
+#include <vector>
+#include "LogMatchingTracker.h"
+#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class SimpleLogMatchingTracker : public virtual LogMatchingTracker {
+public:
+    SimpleLogMatchingTracker(const std::string& name, const int index,
+                             const SimpleLogEntryMatcher& matcher);
+
+    ~SimpleLogMatchingTracker();
+
+    bool init(const std::vector<LogEntryMatcher>& allLogMatchers,
+              const std::vector<sp<LogMatchingTracker>>& allTrackers,
+              const std::unordered_map<std::string, int>& matcherMap,
+              std::vector<bool>& stack) override;
+
+    void onLogEvent(const LogEventWrapper& event,
+                    const std::vector<sp<LogMatchingTracker>>& allTrackers,
+                    std::vector<MatchingState>& matcherResults) override;
+
+private:
+    const SimpleLogEntryMatcher mMatcher;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+#endif  // SIMPLE_LOG_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/LogEntryMatcherManager.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
similarity index 69%
rename from cmds/statsd/src/matchers/LogEntryMatcherManager.cpp
rename to cmds/statsd/src/matchers/matcher_util.cpp
index ab7b2b1d..557c032 100644
--- a/cmds/statsd/src/matchers/LogEntryMatcherManager.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -14,26 +14,28 @@
  * limitations under the License.
  */
 
-#include "LogEntryMatcherManager.h"
+#include "matcher_util.h"
 #include <cutils/log.h>
 #include <log/event_tag_map.h>
 #include <log/log_event_list.h>
 #include <log/logprint.h>
 #include <utils/Errors.h>
 #include <unordered_map>
+#include "LogMatchingTracker.h"
 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "parse_util.h"
+#include "stats_util.h"
 
 using std::set;
 using std::string;
 using std::unordered_map;
+using std::vector;
 
 namespace android {
 namespace os {
 namespace statsd {
 
-LogEventWrapper LogEntryMatcherManager::parseLogEvent(log_msg msg) {
+LogEventWrapper parseLogEvent(log_msg msg) {
     LogEventWrapper wrapper;
     wrapper.timestamp_ns = msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec;
     wrapper.tagId = getTagId(msg);
@@ -67,7 +69,9 @@
                     break;
                 case EVENT_TYPE_STRING:
                     if (index % 2 == 1) {
-                        wrapper.strMap[key] = elem.data.string;
+                        // without explicit calling string() constructor, there will be an
+                        // additional 0 in the end of the string.
+                        wrapper.strMap[key] = string(elem.data.string);
                     }
                     index++;
                     break;
@@ -99,57 +103,56 @@
     return wrapper;
 }
 
-bool LogEntryMatcherManager::matches(const LogEntryMatcher& matcher, const LogEventWrapper& event) {
-    const int tagId = event.tagId;
-    const unordered_map<int, long>& intMap = event.intMap;
-    const unordered_map<int, string>& strMap = event.strMap;
-    const unordered_map<int, float>& floatMap = event.floatMap;
-    const unordered_map<int, bool>& boolMap = event.boolMap;
-
-    if (matcher.has_combination()) {  // Need to evaluate composite matching
-        switch (matcher.combination().operation()) {
-            case LogicalOperation::AND:
-                for (auto nestedMatcher : matcher.combination().matcher()) {
-                    if (!matches(nestedMatcher, event)) {
-                        return false;  // return false if any nested matcher is false;
-                    }
+bool combinationMatch(const vector<int>& children, const LogicalOperation& operation,
+                      const vector<MatchingState>& matcherResults) {
+    bool matched;
+    switch (operation) {
+        case LogicalOperation::AND: {
+            matched = true;
+            for (const int childIndex : children) {
+                if (matcherResults[childIndex] != MatchingState::kMatched) {
+                    matched = false;
+                    break;
                 }
-                return true;  // Otherwise, return true.
-            case LogicalOperation::OR:
-                for (auto nestedMatcher : matcher.combination().matcher()) {
-                    if (matches(nestedMatcher, event)) {
-                        return true;  // return true if any nested matcher is true;
-                    }
-                }
-                return false;
-            case LogicalOperation::NOT:
-                return !matches(matcher.combination().matcher(0), event);
-
-            // Case NAND is just inverting the return statement of AND
-            case LogicalOperation::NAND:
-                for (auto nestedMatcher : matcher.combination().matcher()) {
-                    auto simple = nestedMatcher.simple_log_entry_matcher();
-                    if (!matches(nestedMatcher, event)) {
-                        return true;  // return false if any nested matcher is false;
-                    }
-                }
-                return false;  // Otherwise, return true.
-            case LogicalOperation::NOR:
-                for (auto nestedMatcher : matcher.combination().matcher()) {
-                    if (matches(nestedMatcher, event)) {
-                        return false;  // return true if any nested matcher is true;
-                    }
-                }
-                return true;
+            }
+            break;
         }
-        return false;
-    } else {
-        return matchesSimple(matcher.simple_log_entry_matcher(), event);
+        case LogicalOperation::OR: {
+            matched = false;
+            for (const int childIndex : children) {
+                if (matcherResults[childIndex] == MatchingState::kMatched) {
+                    matched = true;
+                    break;
+                }
+            }
+            break;
+        }
+        case LogicalOperation::NOT:
+            matched = matcherResults[children[0]] == MatchingState::kNotMatched;
+            break;
+        case LogicalOperation::NAND:
+            matched = false;
+            for (const int childIndex : children) {
+                if (matcherResults[childIndex] != MatchingState::kMatched) {
+                    matched = true;
+                    break;
+                }
+            }
+            break;
+        case LogicalOperation::NOR:
+            matched = true;
+            for (const int childIndex : children) {
+                if (matcherResults[childIndex] == MatchingState::kMatched) {
+                    matched = false;
+                    break;
+                }
+            }
+            break;
     }
+    return matched;
 }
 
-bool LogEntryMatcherManager::matchesSimple(const SimpleLogEntryMatcher& simpleMatcher,
-                                           const LogEventWrapper& event) {
+bool matchesSimple(const SimpleLogEntryMatcher& simpleMatcher, const LogEventWrapper& event) {
     const int tagId = event.tagId;
     const unordered_map<int, long>& intMap = event.intMap;
     const unordered_map<int, string>& strMap = event.strMap;
@@ -249,26 +252,6 @@
     return false;
 }
 
-set<int> LogEntryMatcherManager::getTagIdsFromMatcher(const LogEntryMatcher& matcher) {
-    set<int> result;
-    switch (matcher.contents_case()) {
-        case LogEntryMatcher::kCombination:
-            for (auto sub_matcher : matcher.combination().matcher()) {
-                set<int> tagSet = getTagIdsFromMatcher(sub_matcher);
-                result.insert(tagSet.begin(), tagSet.end());
-            }
-            break;
-        case LogEntryMatcher::kSimpleLogEntryMatcher:
-            for (int i = 0; i < matcher.simple_log_entry_matcher().tag_size(); i++) {
-                result.insert(matcher.simple_log_entry_matcher().tag(i));
-            }
-            break;
-        case LogEntryMatcher::CONTENTS_NOT_SET:
-            break;
-    }
-    return result;
-}
-
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/matchers/LogEntryMatcherManager.h b/cmds/statsd/src/matchers/matcher_util.h
similarity index 63%
rename from cmds/statsd/src/matchers/LogEntryMatcherManager.h
rename to cmds/statsd/src/matchers/matcher_util.h
index fc8e6a1..6d8e762 100644
--- a/cmds/statsd/src/matchers/LogEntryMatcherManager.h
+++ b/cmds/statsd/src/matchers/matcher_util.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef LOG_ENTRY_MATCHER_MANAGER_H
-#define LOG_ENTRY_MATCHER_MANAGER_H
+#ifndef MATCHER_UTIL_H
+#define MATCHER_UTIL_H
 
 #include <log/log_read.h>
 #include <log/logprint.h>
@@ -25,9 +25,6 @@
 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 
-using std::string;
-using std::unordered_map;
-
 namespace android {
 namespace os {
 namespace statsd {
@@ -41,26 +38,20 @@
     std::unordered_map<int, float> floatMap;
 } LogEventWrapper;
 
-/**
- * Keeps track per log entry which simple log entry matchers match.
- */
-class LogEntryMatcherManager {
-public:
-    LogEntryMatcherManager();
-
-    ~LogEntryMatcherManager(){};
-
-    static LogEventWrapper parseLogEvent(log_msg msg);
-
-    static std::set<int> getTagIdsFromMatcher(const LogEntryMatcher& matcher);
-
-    static bool matches(const LogEntryMatcher& matcher, const LogEventWrapper& wrapper);
-
-    static bool matchesSimple(const SimpleLogEntryMatcher& simpleMatcher,
-                              const LogEventWrapper& wrapper);
+enum MatchingState {
+    kNotComputed = -1,
+    kNotMatched = 0,
+    kMatched = 1,
 };
 
+LogEventWrapper parseLogEvent(log_msg msg);
+
+bool combinationMatch(const std::vector<int>& children, const LogicalOperation& operation,
+                      const std::vector<MatchingState>& matcherResults);
+
+bool matchesSimple(const SimpleLogEntryMatcher& simpleMatcher, const LogEventWrapper& wrapper);
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
-#endif  // LOG_ENTRY_MATCHER_MANAGER_H
+#endif  // MATCHER_UTIL_H
diff --git a/cmds/statsd/src/metrics/ConditionTracker.cpp b/cmds/statsd/src/metrics/ConditionTracker.cpp
deleted file mode 100644
index 684ffdb..0000000
--- a/cmds/statsd/src/metrics/ConditionTracker.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#define LOG_TAG "ConditionTracker"
-#define DEBUG true  // STOPSHIP if true
-#define VLOG(...) \
-    if (DEBUG) ALOGD(__VA_ARGS__);
-
-#include "ConditionTracker.h"
-#include <cutils/log.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-ConditionTracker::ConditionTracker() : mIsConditionMet(true) {
-    VLOG("ConditionTracker()");
-}
-
-ConditionTracker::ConditionTracker(const Condition& condition)
-    : mCondition(condition), mIsConditionMet(true) {
-    VLOG("ConditionTracker()");
-}
-
-ConditionTracker::~ConditionTracker() {
-    VLOG("~ConditionTracker()");
-}
-
-void ConditionTracker::evaluateCondition(const LogEventWrapper& event) {
-    // modify condition.
-    VLOG("evaluateCondition");
-}
-
-bool ConditionTracker::isConditionMet() const {
-    VLOG("isConditionMet() %d", mIsConditionMet);
-    return mIsConditionMet;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 635777f..e98999e 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -21,7 +21,6 @@
 
 #include "CountMetricProducer.h"
 #include "CountAnomalyTracker.h"
-#include "parse_util.h"
 
 #include <cutils/log.h>
 #include <limits.h>
@@ -33,15 +32,14 @@
 namespace os {
 namespace statsd {
 
-CountMetricProducer::CountMetricProducer(const CountMetric& metric,
-                                         const sp<ConditionTracker> condition)
+CountMetricProducer::CountMetricProducer(const CountMetric& metric, const bool hasCondition)
     : mMetric(metric),
-      mConditionTracker(condition),
-      mStartTime(std::time(nullptr)),
+      mStartTime(time(nullptr)),
       mCounter(0),
       mCurrentBucketStartTime(mStartTime),
       // TODO: read mAnomalyTracker parameters from config file.
-      mAnomalyTracker(6, 10) {
+      mAnomalyTracker(6, 10),
+      mCondition(hasCondition ? ConditionState::kUnknown : ConditionState::kTrue) {
     // TODO: evaluate initial conditions. and set mConditionMet.
     if (metric.has_bucket() && metric.bucket().has_bucket_size_millis()) {
         mBucketSize_sec = metric.bucket().bucket_size_millis() / 1000;
@@ -52,10 +50,6 @@
     VLOG("created. bucket size %lu start_time: %lu", mBucketSize_sec, mStartTime);
 }
 
-CountMetricProducer::CountMetricProducer(const CountMetric& metric)
-    : CountMetricProducer(metric, new ConditionTracker()) {
-}
-
 CountMetricProducer::~CountMetricProducer() {
     VLOG("~CountMetricProducer() called");
 }
@@ -63,13 +57,17 @@
 void CountMetricProducer::finish() {
     // TODO: write the StatsLogReport to dropbox using
     // DropboxWriter.
-    onDumpReport();
 }
 
 void CountMetricProducer::onDumpReport() {
     VLOG("dump report now...");
 }
 
+void CountMetricProducer::onConditionChanged(const bool conditionMet) {
+    VLOG("onConditionChanged");
+    mCondition = conditionMet;
+}
+
 void CountMetricProducer::onMatchedLogEvent(const LogEventWrapper& event) {
     time_t eventTime = event.timestamp_ns / 1000000000;
 
@@ -78,22 +76,24 @@
         return;
     }
 
-    if (mConditionTracker->isConditionMet()) {
+    if (mCondition == ConditionState::kTrue) {
         flushCounterIfNeeded(eventTime);
         mCounter++;
         mAnomalyTracker.checkAnomaly(mCounter);
+        VLOG("metric %lld count %d", mMetric.metric_id(), mCounter);
     }
 }
 
-// When a new matched event comes in, we check if it falls into the current bucket. And flush the
-// counter to the StatsLogReport and adjust the bucket if needed.
+// When a new matched event comes in, we check if it falls into the current
+// bucket. And flush the counter to the StatsLogReport and adjust the bucket if
+// needed.
 void CountMetricProducer::flushCounterIfNeeded(const time_t& eventTime) {
     if (mCurrentBucketStartTime + mBucketSize_sec > eventTime) {
         return;
     }
 
     // TODO: add a KeyValuePair to StatsLogReport.
-    ALOGD("CountMetric: dump counter %d", mCounter);
+    ALOGD("%lld:  dump counter %d", mMetric.metric_id(), mCounter);
 
     // adjust the bucket start time
     time_t numBucketsForward = (eventTime - mCurrentBucketStartTime)
@@ -106,7 +106,7 @@
     mAnomalyTracker.addPastBucket(mCounter, numBucketsForward);
     mCounter = 0;
 
-    VLOG("new bucket start time: %lu", mCurrentBucketStartTime);
+    VLOG("%lld: new bucket start time: %lu", mMetric.metric_id(), mCurrentBucketStartTime);
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 7502320..370cd468 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -17,40 +17,41 @@
 #ifndef COUNT_METRIC_PRODUCER_H
 #define COUNT_METRIC_PRODUCER_H
 
-#include <mutex>
-#include <thread>
 #include <unordered_map>
-#include "../matchers/LogEntryMatcherManager.h"
+
 #include "CountAnomalyTracker.h"
-#include "ConditionTracker.h"
-#include "DropboxWriter.h"
+#include "../condition/ConditionTracker.h"
+#include "../matchers/matcher_util.h"
 #include "MetricProducer.h"
 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 
+using namespace std;
+
 namespace android {
 namespace os {
 namespace statsd {
 
 class CountMetricProducer : public MetricProducer {
 public:
-    CountMetricProducer(const CountMetric& countMetric, const sp<ConditionTracker> condition);
-
-    CountMetricProducer(const CountMetric& countMetric);
+    CountMetricProducer(const CountMetric& countMetric, const bool hasCondition);
 
     virtual ~CountMetricProducer();
 
     void onMatchedLogEvent(const LogEventWrapper& event) override;
 
+    void onConditionChanged(const bool conditionMet) override;
+
     void finish() override;
 
     void onDumpReport() override;
 
+    // TODO: Implement this later.
+    virtual void notifyAppUpgrade(const string& apk, const int uid, const int version) override {};
+
 private:
     const CountMetric mMetric;
 
-    const sp<ConditionTracker> mConditionTracker;
-
     const time_t mStartTime;
     // TODO: Add dimensions.
     // Counter value for the current bucket.
@@ -62,6 +63,8 @@
 
     CountAnomalyTracker mAnomalyTracker;
 
+    bool mCondition;
+
     void flushCounterIfNeeded(const time_t& newEventTime);
 };
 
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 44a778b..6c39d98 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -18,21 +18,27 @@
 #define METRIC_PRODUCER_H
 
 #include <log/logprint.h>
-#include "../matchers/LogEntryMatcherManager.h"
+#include <utils/RefBase.h>
+#include "../matchers/matcher_util.h"
+#include "PackageInfoListener.h"
 
 namespace android {
 namespace os {
 namespace statsd {
 
 // A MetricProducer is responsible for compute one single metrics, creating stats log report, and
-// writing the report to dropbox.
-class MetricProducer {
+// writing the report to dropbox. MetricProducers should respond to package changes as required in
+// PackageInfoListener, but if none of the metrics are slicing by package name, then the update can
+// be a no-op.
+class MetricProducer : public virtual PackageInfoListener {
 public:
     virtual ~MetricProducer(){};
 
-    // Consume the stats log if it's interesting to this metric.
+    // Consume the parsed stats log entry that already matched the "what" of the metric.
     virtual void onMatchedLogEvent(const LogEventWrapper& event) = 0;
 
+    virtual void onConditionChanged(const bool condition) = 0;
+
     // This is called when the metric collecting is done, e.g., when there is a new configuration
     // coming. MetricProducer should do the clean up, and dump existing data to dropbox.
     virtual void finish() = 0;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index cb74206..1e65f58 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -21,13 +21,17 @@
 #include "MetricsManager.h"
 #include <cutils/log.h>
 #include <log/logprint.h>
+#include "../condition/CombinationConditionTracker.h"
+#include "../condition/SimpleConditionTracker.h"
+#include "../matchers/CombinationLogMatchingTracker.h"
+#include "../matchers/SimpleLogMatchingTracker.h"
 #include "CountMetricProducer.h"
-#include "parse_util.h"
+#include "metrics_manager_util.h"
+#include "stats_util.h"
 
 using std::make_unique;
 using std::set;
 using std::string;
-using std::unique_ptr;
 using std::unordered_map;
 using std::vector;
 
@@ -35,93 +39,90 @@
 namespace os {
 namespace statsd {
 
-MetricsManager::MetricsManager(const StatsdConfig& config) : mConfig(config), mLogMatchers() {
-    std::unordered_map<string, LogEntryMatcher> matcherMap;
-    std::unordered_map<string, sp<ConditionTracker>> conditionMap;
-
-    for (int i = 0; i < config.log_entry_matcher_size(); i++) {
-        const LogEntryMatcher& logMatcher = config.log_entry_matcher(i);
-        mMatchers.push_back(logMatcher);
-
-        matcherMap[config.log_entry_matcher(i).name()] = logMatcher;
-
-        mLogMatchers[logMatcher.name()] = vector<unique_ptr<MetricProducer>>();
-        // Collect all the tag ids that are interesting
-        set<int> tagIds = LogEntryMatcherManager::getTagIdsFromMatcher(logMatcher);
-
-        mTagIds.insert(tagIds.begin(), tagIds.end());
-    }
-
-    for (int i = 0; i < config.condition_size(); i++) {
-        const Condition& condition = config.condition(i);
-        conditionMap[condition.name()] = new ConditionTracker(condition);
-    }
-
-    // Build MetricProducers for each metric defined in config.
-    // (1) build CountMetricProducer
-    for (int i = 0; i < config.count_metric_size(); i++) {
-        const CountMetric& metric = config.count_metric(i);
-        auto it = mLogMatchers.find(metric.what());
-        if (it == mLogMatchers.end()) {
-            ALOGW("cannot find the LogEntryMatcher %s in config", metric.what().c_str());
-            continue;
-        }
-
-        if (metric.has_condition()) {
-            auto condition_it = conditionMap.find(metric.condition());
-            if (condition_it == conditionMap.end()) {
-                ALOGW("cannot find the Condition %s in the config", metric.condition().c_str());
-                continue;
-            }
-            it->second.push_back(make_unique<CountMetricProducer>(metric, condition_it->second));
-        } else {
-            it->second.push_back(make_unique<CountMetricProducer>(metric));
-        }
-    }
-
-    // TODO: build other types of metrics too.
+MetricsManager::MetricsManager(const StatsdConfig& config) {
+    mConfigValid = initStatsdConfig(config, mTagIds, mAllLogEntryMatchers, mAllConditionTrackers,
+                                    mAllMetricProducers, mConditionToMetricMap, mTrackerToMetricMap,
+                                    mTrackerToConditionMap);
 }
 
 MetricsManager::~MetricsManager() {
     VLOG("~MetricManager()");
 }
 
+bool MetricsManager::isConfigValid() const {
+    return mConfigValid;
+}
+
 void MetricsManager::finish() {
-    for (auto const& entryPair : mLogMatchers) {
-        for (auto const& metric : entryPair.second) {
-            metric->finish();
-        }
+    for (auto& metricProducer : mAllMetricProducers) {
+        metricProducer->finish();
     }
 }
 
 // Consume the stats log if it's interesting to this metric.
 void MetricsManager::onLogEvent(const log_msg& logMsg) {
+    if (!mConfigValid) {
+        return;
+    }
+
     int tagId = getTagId(logMsg);
     if (mTagIds.find(tagId) == mTagIds.end()) {
         // not interesting...
         return;
     }
-    // Since at least one of the metrics is interested in this event, we parse it now.
-    LogEventWrapper event = LogEntryMatcherManager::parseLogEvent(logMsg);
 
-    // Evaluate the conditions. Order matters, this should happen
-    // before sending the event to metrics
-    for (auto& condition : mConditionTracker) {
-        condition->evaluateCondition(event);
+    // Since at least one of the metrics is interested in this event, we parse it now.
+    LogEventWrapper event = parseLogEvent(logMsg);
+    vector<MatchingState> matcherCache(mAllLogEntryMatchers.size(), MatchingState::kNotComputed);
+
+    for (auto& matcher : mAllLogEntryMatchers) {
+        matcher->onLogEvent(event, mAllLogEntryMatchers, matcherCache);
     }
 
-    // Now find out which LogMatcher matches this event, and let relevant metrics know.
-    for (auto matcher : mMatchers) {
-        if (LogEntryMatcherManager::matches(matcher, event)) {
-            auto it = mLogMatchers.find(matcher.name());
-            if (it != mLogMatchers.end()) {
-                for (auto const& it2 : it->second) {
-                    // Only metrics that matches this event get notified.
-                    it2->onMatchedLogEvent(event);
+    // A bitmap to see which ConditionTracker needs to be re-evaluated.
+    vector<bool> conditionToBeEvaluated(mAllConditionTrackers.size(), false);
+
+    for (const auto& pair : mTrackerToConditionMap) {
+        if (matcherCache[pair.first] == MatchingState::kMatched) {
+            const auto& conditionList = pair.second;
+            for (const int conditionIndex : conditionList) {
+                conditionToBeEvaluated[conditionIndex] = true;
+            }
+        }
+    }
+
+    vector<ConditionState> conditionCache(mAllConditionTrackers.size(),
+                                          ConditionState::kNotEvaluated);
+    // A bitmap to track if a condition has changed value.
+    vector<bool> changedCache(mAllConditionTrackers.size(), false);
+    for (size_t i = 0; i < mAllConditionTrackers.size(); i++) {
+        if (conditionToBeEvaluated[i] == false) {
+            continue;
+        }
+
+        sp<ConditionTracker>& condition = mAllConditionTrackers[i];
+        condition->evaluateCondition(event, matcherCache, mAllConditionTrackers, conditionCache,
+                                     changedCache);
+        if (changedCache[i]) {
+            auto pair = mConditionToMetricMap.find(i);
+            if (pair != mConditionToMetricMap.end()) {
+                auto& metricList = pair->second;
+                for (auto metricIndex : metricList) {
+                    mAllMetricProducers[metricIndex]->onConditionChanged(conditionCache[i]);
                 }
-            } else {
-                // TODO: we should remove any redundant matchers that the config provides.
-                ALOGW("Matcher not used by any metrics.");
+            }
+        }
+    }
+
+    // For matched LogEntryMatchers, tell relevant metrics that a matched event has come.
+    for (size_t i = 0; i < mAllLogEntryMatchers.size(); i++) {
+        if (matcherCache[i] == MatchingState::kMatched) {
+            auto pair = mTrackerToMetricMap.find(i);
+            if (pair != mTrackerToMetricMap.end()) {
+                auto& metricList = pair->second;
+                for (const int metricIndex : metricList) {
+                    mAllMetricProducers[metricIndex]->onMatchedLogEvent(event);
+                }
             }
         }
     }
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 77d7535..70c34db 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -20,8 +20,8 @@
 #include <cutils/log.h>
 #include <log/logprint.h>
 #include <unordered_map>
-#include "../matchers/LogEntryMatcherManager.h"
-#include "ConditionTracker.h"
+#include "../condition/ConditionTracker.h"
+#include "../matchers/LogMatchingTracker.h"
 #include "MetricProducer.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 
@@ -36,25 +36,58 @@
 
     ~MetricsManager();
 
-    // Consume the stats log if it's interesting to this metric.
+    // Return whether the configuration is valid.
+    bool isConfigValid() const;
+
     void onLogEvent(const log_msg& logMsg);
 
+    // Called when everything should wrap up. We are about to finish (e.g., new config comes).
     void finish();
 
 private:
-    const StatsdConfig mConfig;
-
     // All event tags that are interesting to my metrics.
     std::set<int> mTagIds;
 
-    // The matchers that my metrics share.
-    std::vector<LogEntryMatcher> mMatchers;
+    // We only store the sp of LogMatchingTracker, MetricProducer, and ConditionTracker in
+    // MetricManager. There are relationship between them, and the relationship are denoted by index
+    // instead of poiters. The reasons for this are: (1) the relationship between them are
+    // complicated, store index instead of pointers reduce the risk of A holds B's sp, and B holds
+    // A's sp. (2) When we evaluate matcher results, or condition results, we can quickly get the
+    // related results from a cache using the index.
+    // TODO: using unique_ptr may be more appriopreate?
 
-    // The conditions that my metrics share.
-    std::vector<sp<ConditionTracker>> mConditionTracker;
+    // Hold all the log entry matchers from the config.
+    std::vector<sp<LogMatchingTracker>> mAllLogEntryMatchers;
 
-    // the map from LogEntryMatcher names to the metrics that use this matcher.
-    std::unordered_map<std::string, std::vector<std::unique_ptr<MetricProducer>>> mLogMatchers;
+    // Hold all the conditions from the config.
+    std::vector<sp<ConditionTracker>> mAllConditionTrackers;
+
+    // Hold all metrics from the config.
+    std::vector<sp<MetricProducer>> mAllMetricProducers;
+
+    // To make the log processing more efficient, we want to do as much filtering as possible
+    // before we go into individual trackers and conditions to match.
+
+    // 1st filter: check if the event tag id is in mTagIds.
+    // 2nd filter: if it is, we parse the event because there is at least one member is interested.
+    //             then pass to all LogMatchingTrackers (itself also filter events by ids).
+    // 3nd filter: for LogMatchingTrackers that matched this event, we pass this event to the
+    //             ConditionTrackers and MetricProducers that use this matcher.
+    // 4th filter: for ConditionTrackers that changed value due to this event, we pass
+    //             new conditions to  metrics that use this condition.
+
+    // The following map is initialized from the statsd_config.
+
+    // maps from the index of the LogMatchingTracker to index of MetricProducer.
+    std::unordered_map<int, std::vector<int>> mTrackerToMetricMap;
+
+    // maps from LogMatchingTracker to ConditionTracker
+    std::unordered_map<int, std::vector<int>> mTrackerToConditionMap;
+
+    // maps from ConditionTracker to MetricProducer
+    std::unordered_map<int, std::vector<int>> mConditionToMetricMap;
+
+    bool mConfigValid;
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
new file mode 100644
index 0000000..6fdd228
--- /dev/null
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "../condition/CombinationConditionTracker.h"
+#include "../condition/SimpleConditionTracker.h"
+#include "../matchers/CombinationLogMatchingTracker.h"
+#include "../matchers/SimpleLogMatchingTracker.h"
+#include "CountMetricProducer.h"
+#include "stats_util.h"
+
+using std::set;
+using std::string;
+using std::unordered_map;
+using std::vector;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+bool initLogTrackers(const StatsdConfig& config, unordered_map<string, int>& logTrackerMap,
+                     vector<sp<LogMatchingTracker>>& allLogEntryMatchers, set<int>& allTagIds) {
+    vector<LogEntryMatcher> matcherConfigs;
+
+    for (int i = 0; i < config.log_entry_matcher_size(); i++) {
+        const LogEntryMatcher& logMatcher = config.log_entry_matcher(i);
+
+        int index = allLogEntryMatchers.size();
+        switch (logMatcher.contents_case()) {
+            case LogEntryMatcher::ContentsCase::kSimpleLogEntryMatcher:
+                allLogEntryMatchers.push_back(new SimpleLogMatchingTracker(
+                        logMatcher.name(), index, logMatcher.simple_log_entry_matcher()));
+                break;
+            case LogEntryMatcher::ContentsCase::kCombination:
+                allLogEntryMatchers.push_back(
+                        new CombinationLogMatchingTracker(logMatcher.name(), index));
+                break;
+            default:
+                ALOGE("Matcher %s malformed", logMatcher.name().c_str());
+                return false;
+                // continue;
+        }
+        if (logTrackerMap.find(logMatcher.name()) != logTrackerMap.end()) {
+            ALOGE("Duplicate LogEntryMatcher found!");
+            return false;
+        }
+        logTrackerMap[logMatcher.name()] = index;
+        matcherConfigs.push_back(logMatcher);
+    }
+
+    vector<bool> stackTracker2(allLogEntryMatchers.size(), false);
+    for (auto& matcher : allLogEntryMatchers) {
+        if (!matcher->init(matcherConfigs, allLogEntryMatchers, logTrackerMap, stackTracker2)) {
+            return false;
+        }
+        // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
+        const set<int>& tagIds = matcher->getTagIds();
+        allTagIds.insert(tagIds.begin(), tagIds.end());
+    }
+    return true;
+}
+
+bool initConditions(const StatsdConfig& config, const unordered_map<string, int>& logTrackerMap,
+                    unordered_map<string, int>& conditionTrackerMap,
+                    vector<sp<ConditionTracker>>& allConditionTrackers,
+                    unordered_map<int, std::vector<int>>& trackerToConditionMap) {
+    vector<Condition> conditionConfigs;
+
+    for (int i = 0; i < config.condition_size(); i++) {
+        const Condition& condition = config.condition(i);
+        int index = allConditionTrackers.size();
+        switch (condition.contents_case()) {
+            case Condition::ContentsCase::kSimpleCondition: {
+                allConditionTrackers.push_back(new SimpleConditionTracker(
+                        condition.name(), index, condition.simple_condition(), logTrackerMap));
+                break;
+            }
+            case Condition::ContentsCase::kCombination: {
+                allConditionTrackers.push_back(
+                        new CombinationConditionTracker(condition.name(), index));
+                break;
+            }
+            default:
+                ALOGE("Condition %s malformed", condition.name().c_str());
+                return false;
+        }
+        if (conditionTrackerMap.find(condition.name()) != conditionTrackerMap.end()) {
+            ALOGE("Duplicate Condition found!");
+            return false;
+        }
+        conditionTrackerMap[condition.name()] = index;
+        conditionConfigs.push_back(condition);
+    }
+
+    vector<bool> stackTracker(allConditionTrackers.size(), false);
+    for (size_t i = 0; i < allConditionTrackers.size(); i++) {
+        auto& conditionTracker = allConditionTrackers[i];
+        if (!conditionTracker->init(conditionConfigs, allConditionTrackers, conditionTrackerMap,
+                                    stackTracker)) {
+            return false;
+        }
+        for (const int trackerIndex : conditionTracker->getLogTrackerIndex()) {
+            auto& conditionList = trackerToConditionMap[trackerIndex];
+            conditionList.push_back(i);
+        }
+    }
+    return true;
+}
+
+bool initMetrics(const StatsdConfig& config, const unordered_map<string, int>& logTrackerMap,
+                 const unordered_map<string, int>& conditionTrackerMap,
+                 vector<sp<MetricProducer>>& allMetricProducers,
+                 unordered_map<int, std::vector<int>>& conditionToMetricMap,
+                 unordered_map<int, std::vector<int>>& trackerToMetricMap) {
+    // Build MetricProducers for each metric defined in config.
+    // (1) build CountMetricProducer
+    for (int i = 0; i < config.count_metric_size(); i++) {
+        const CountMetric& metric = config.count_metric(i);
+        if (!metric.has_what()) {
+            ALOGW("cannot find what in CountMetric %lld", metric.metric_id());
+            return false;
+        }
+
+        auto logTrackerIt = logTrackerMap.find(metric.what());
+        if (logTrackerIt == logTrackerMap.end()) {
+            ALOGW("cannot find the LogEntryMatcher %s in config", metric.what().c_str());
+            return false;
+        }
+
+        sp<MetricProducer> countProducer;
+        int metricIndex = allMetricProducers.size();
+        if (metric.has_condition()) {
+            auto condition_it = conditionTrackerMap.find(metric.condition());
+            if (condition_it == conditionTrackerMap.end()) {
+                ALOGW("cannot find the Condition %s in the config", metric.condition().c_str());
+                return false;
+            }
+            countProducer = new CountMetricProducer(metric, true /*has condition*/);
+            // will create new vector if not exist before.
+            auto& metricList = conditionToMetricMap[condition_it->second];
+            metricList.push_back(metricIndex);
+        } else {
+            countProducer = new CountMetricProducer(metric, false /*no condition*/);
+        }
+
+        int logTrackerIndex = logTrackerIt->second;
+        auto& metric_list = trackerToMetricMap[logTrackerIndex];
+        metric_list.push_back(metricIndex);
+        allMetricProducers.push_back(countProducer);
+    }
+
+    // TODO: build other types of metrics too.
+
+    return true;
+}
+
+bool initStatsdConfig(const StatsdConfig& config, set<int>& allTagIds,
+                      vector<sp<LogMatchingTracker>>& allLogEntryMatchers,
+                      vector<sp<ConditionTracker>>& allConditionTrackers,
+                      vector<sp<MetricProducer>>& allMetricProducers,
+                      unordered_map<int, std::vector<int>>& conditionToMetricMap,
+                      unordered_map<int, std::vector<int>>& trackerToMetricMap,
+                      unordered_map<int, std::vector<int>>& trackerToConditionMap) {
+    unordered_map<string, int> logTrackerMap;
+    unordered_map<string, int> conditionTrackerMap;
+
+    if (!initLogTrackers(config, logTrackerMap, allLogEntryMatchers, allTagIds)) {
+        ALOGE("initLogMatchingTrackers failed");
+        return false;
+    }
+
+    if (!initConditions(config, logTrackerMap, conditionTrackerMap, allConditionTrackers,
+                        trackerToConditionMap)) {
+        ALOGE("initConditionTrackers failed");
+        return false;
+    }
+
+    if (!initMetrics(config, logTrackerMap, conditionTrackerMap, allMetricProducers,
+                     conditionToMetricMap, trackerToMetricMap)) {
+        ALOGE("initMetricProducers failed");
+        return false;
+    }
+    return true;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
new file mode 100644
index 0000000..5f1f295
--- /dev/null
+++ b/cmds/statsd/src/metrics/metrics_manager_util.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+#ifndef METRIC_UTIL_H
+#define METRIC_UTIL_H
+#include <memory>
+#include <set>
+#include <unordered_map>
+#include <vector>
+
+#include "../condition/ConditionTracker.h"
+#include "../matchers/LogMatchingTracker.h"
+#include "CountMetricProducer.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+// Helper functions for MetricsManager to initialize from StatsdConfig.
+// *Note*: only initStatsdConfig() should be called from outside.
+// All other functions are intermediate
+// steps, created to make unit tests easier. And most of the parameters in these
+// functions are temporary objects in the initialization phase.
+
+// Initialize the LogMatchingTrackers.
+// input:
+// [config]: the input StatsdConfig
+// output:
+// [logTrackerMap]: this map should contain matcher name to index mapping
+// [allLogEntryMatchers]: should store the sp to all the LogMatchingTracker
+// [allTagIds]: contains the set of all interesting tag ids to this config.
+bool initLogTrackers(const StatsdConfig& config,
+                     std::unordered_map<std::string, int>& logTrackerMap,
+                     std::vector<sp<LogMatchingTracker>>& allLogEntryMatchers,
+                     std::set<int>& allTagIds);
+
+// Initialize ConditionTrackers
+// input:
+// [config]: the input config
+// [logTrackerMap]: LogMatchingTracker name to index mapping from previous step.
+// output:
+// [conditionTrackerMap]: this map should contain condition name to index mapping
+// [allConditionTrackers]: stores the sp to all the ConditionTrackers
+// [trackerToConditionMap]: contain the mapping from index of
+//                        log tracker to condition trackers that use the log tracker
+bool initConditions(const StatsdConfig& config,
+                    const std::unordered_map<std::string, int>& logTrackerMap,
+                    std::unordered_map<std::string, int>& conditionTrackerMap,
+                    std::vector<sp<ConditionTracker>>& allConditionTrackers,
+                    std::unordered_map<int, std::vector<int>>& trackerToConditionMap);
+
+// Initialize MetricProducers.
+// input:
+// [config]: the input config
+// [logTrackerMap]: LogMatchingTracker name to index mapping from previous step.
+// [conditionTrackerMap]: condition name to index mapping
+// output:
+// [allMetricProducers]: contains the list of sp to the MetricProducers created.
+// [conditionToMetricMap]: contains the mapping from condition tracker index to
+//                          the list of MetricProducer index
+// [trackerToMetricMap]: contains the mapping from log tracker to MetricProducer index.
+bool initMetrics(const StatsdConfig& config,
+                 const std::unordered_map<std::string, int>& logTrackerMap,
+                 const std::unordered_map<std::string, int>& conditionTrackerMap,
+                 std::vector<sp<MetricProducer>>& allMetricProducers,
+                 std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
+                 std::unordered_map<int, std::vector<int>>& trackerToMetricMap);
+
+// Initialize MetricManager from StatsdConfig.
+// Parameters are the members of MetricsManager. See MetricsManager for declaration.
+bool initStatsdConfig(const StatsdConfig& config, std::set<int>& allTagIds,
+                      std::vector<sp<LogMatchingTracker>>& allLogEntryMatchers,
+                      std::vector<sp<ConditionTracker>>& allConditionTrackers,
+                      std::vector<sp<MetricProducer>>& allMetricProducers,
+                      std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
+                      std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
+                      std::unordered_map<int, std::vector<int>>& trackerToConditionMap);
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+#endif  // METRIC_UTIL_H
diff --git a/cmds/statsd/src/parse_util.cpp b/cmds/statsd/src/parse_util.cpp
deleted file mode 100644
index 61421880..0000000
--- a/cmds/statsd/src/parse_util.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <log/log_event_list.h>
-#include <parse_util.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static inline uint32_t get4LE(const char* src) {
-    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
-}
-
-int getTagId(log_msg msg) {
-    return get4LE(msg.msg());
-}
-
-EventMetricData parse(log_msg msg) {
-    // dump all statsd logs to dropbox for now.
-    // TODO: Add filtering, aggregation, etc.
-    EventMetricData eventMetricData;
-
-    // set tag.
-    int tag = getTagId(msg);
-    // TODO: Replace the following line when we can serialize on the fly.
-    //eventMetricData.set_tag(tag);
-
-    // set timestamp of the event.
-    eventMetricData.set_timestamp_nanos(msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec);
-
-    // start iterating k,v pairs.
-    android_log_context context =
-            create_android_log_parser(const_cast<log_msg*>(&msg)->msg() + sizeof(uint32_t),
-                                      const_cast<log_msg*>(&msg)->len() - sizeof(uint32_t));
-    android_log_list_element elem;
-
-    if (context) {
-        memset(&elem, 0, sizeof(elem));
-        size_t index = 0;
-        int32_t key = -1;
-
-        do {
-            elem = android_log_read_next(context);
-            switch ((int)elem.type) {
-                case EVENT_TYPE_INT:
-                    if (index % 2 == 0) {
-                        key = elem.data.int32;
-                    } else {
-                        // TODO: Fix the following lines when we can serialize on the fly.
-                        /*
-                        int32_t val = elem.data.int32;
-                        KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
-                        keyValuePair->set_key(key);
-                        keyValuePair->set_value_int(val);
-                        */
-                    }
-                    index++;
-                    break;
-                case EVENT_TYPE_FLOAT:
-                    if (index % 2 == 1) {
-                        // TODO: Fix the following lines when we can serialize on the fly.
-                        /*
-                        float val = elem.data.float32;
-                        KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
-                        keyValuePair->set_key(key);
-                        keyValuePair->set_value_float(val);
-                        */
-                    }
-                    index++;
-                    break;
-                case EVENT_TYPE_STRING:
-                    if (index % 2 == 1) {
-                        // TODO: Fix the following lines when we can serialize on the fly.
-                        /*
-                        char* val = elem.data.string;
-                        KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
-                        keyValuePair->set_key(key);
-                        keyValuePair->set_value_str(val);
-                        */
-                    }
-                    index++;
-                    break;
-                case EVENT_TYPE_LONG:
-                    if (index % 2 == 1) {
-                        // TODO: Fix the following lines when we can serialize on the fly.
-                        /*
-                        int64_t val = elem.data.int64;
-                        KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
-                        keyValuePair->set_key(key);
-                        keyValuePair->set_value_int(val);
-                        */
-                    }
-                    index++;
-                    break;
-                case EVENT_TYPE_LIST:
-                    break;
-                case EVENT_TYPE_LIST_STOP:
-                    break;
-                case EVENT_TYPE_UNKNOWN:
-                    break;
-                default:
-                    elem.complete = true;
-                    break;
-            }
-
-            if (elem.complete) {
-                break;
-            }
-        } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
-
-        android_log_destroy(&context);
-    }
-
-    return eventMetricData;
-}
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 2dc0cc7..6421b70 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -55,6 +55,43 @@
   repeated CountBucketInfo bucket_info = 2;
 }
 
+message DurationBucketInfo {
+  optional int64 start_bucket_nanos = 1;
+
+  optional int64 end_bucket_nanos = 2;
+
+  optional int64 duration_nanos = 3;
+}
+
+message DurationMetricData {
+  repeated KeyValuePair dimension = 1;
+
+  repeated DurationBucketInfo bucket_info = 2;
+}
+
+message UidMapping {
+  message AppInfo {
+    optional string app = 1;
+
+    optional int32 version = 2;
+
+    optional int32 uid = 3;
+  }
+
+  repeated AppInfo initial = 1;
+
+  message Change {
+    optional bool deletion = 1;
+
+    optional int64 timestamp = 2;
+    optional string app = 3;
+    optional int32 uid = 4;
+
+    optional int32 version = 5;
+  }
+  repeated Change changes = 2;
+}
+
 message StatsLogReport {
   optional int32 metric_id = 1;
 
@@ -68,8 +105,12 @@
   message CountMetricDataWrapper {
     repeated CountMetricData data = 1;
   }
+  message DurationMetricDataWrapper {
+    repeated CountMetricData data = 1;
+  }
   oneof data {
     EventMetricDataWrapper event_metrics = 4;
     CountMetricDataWrapper count_metrics = 5;
+    DurationMetricDataWrapper duration_metrics = 6;
   }
 }
diff --git a/cmds/statsd/src/stats_util.cpp b/cmds/statsd/src/stats_util.cpp
new file mode 100644
index 0000000..978b228
--- /dev/null
+++ b/cmds/statsd/src/stats_util.cpp
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include <log/log_event_list.h>
+#include "stats_util.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+static inline uint32_t get4LE(const char* src) {
+    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+}
+
+int getTagId(log_msg msg) {
+    return get4LE(msg.msg());
+}
+
+EventMetricData parse(log_msg msg) {
+    // dump all statsd logs to dropbox for now.
+    // TODO: Add filtering, aggregation, etc.
+    EventMetricData eventMetricData;
+
+    // set tag.
+    int tag = getTagId(msg);
+    // TODO: Replace the following line when we can serialize on the fly.
+    // eventMetricData.set_tag(tag);
+
+    // set timestamp of the event.
+    eventMetricData.set_timestamp_nanos(msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec);
+
+    // start iterating k,v pairs.
+    android_log_context context =
+            create_android_log_parser(const_cast<log_msg*>(&msg)->msg() + sizeof(uint32_t),
+                                      const_cast<log_msg*>(&msg)->len() - sizeof(uint32_t));
+    android_log_list_element elem;
+
+    if (context) {
+        memset(&elem, 0, sizeof(elem));
+        size_t index = 0;
+        int32_t key = -1;
+
+        do {
+            elem = android_log_read_next(context);
+            switch ((int)elem.type) {
+                case EVENT_TYPE_INT:
+                    if (index % 2 == 0) {
+                        key = elem.data.int32;
+                    } else {
+                        // TODO: Fix the following lines when we can serialize on the fly.
+                        /*
+                        int32_t val = elem.data.int32;
+                        KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
+                        keyValuePair->set_key(key);
+                        keyValuePair->set_value_int(val);
+                        */
+                    }
+                    index++;
+                    break;
+                case EVENT_TYPE_FLOAT:
+                    if (index % 2 == 1) {
+                        // TODO: Fix the following lines when we can serialize on the fly.
+                        /*
+                        float val = elem.data.float32;
+                        KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
+                        keyValuePair->set_key(key);
+                        keyValuePair->set_value_float(val);
+                        */
+                    }
+                    index++;
+                    break;
+                case EVENT_TYPE_STRING:
+                    if (index % 2 == 1) {
+                        // TODO: Fix the following lines when we can serialize on the fly.
+                        /*
+                        char* val = elem.data.string;
+                        KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
+                        keyValuePair->set_key(key);
+                        keyValuePair->set_value_str(val);
+                        */
+                    }
+                    index++;
+                    break;
+                case EVENT_TYPE_LONG:
+                    if (index % 2 == 1) {
+                        // TODO: Fix the following lines when we can serialize on the fly.
+                        /*
+                        int64_t val = elem.data.int64;
+                        KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
+                        keyValuePair->set_key(key);
+                        keyValuePair->set_value_int(val);
+                        */
+                    }
+                    index++;
+                    break;
+                case EVENT_TYPE_LIST:
+                    break;
+                case EVENT_TYPE_LIST_STOP:
+                    break;
+                case EVENT_TYPE_UNKNOWN:
+                    break;
+                default:
+                    elem.complete = true;
+                    break;
+            }
+
+            if (elem.complete) {
+                break;
+            }
+        } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
+
+        android_log_destroy(&context);
+    }
+
+    return eventMetricData;
+}
+
+StatsdConfig buildFakeConfig() {
+    // HACK: Hard code a test metric for counting screen on events...
+    StatsdConfig config;
+    config.set_config_id(12345L);
+
+    // One count metric to count screen on
+    CountMetric* metric = config.add_count_metric();
+    metric->set_metric_id(20150717L);
+    metric->set_what("SCREEN_IS_ON");
+    metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
+
+    // One count metric to count PHOTO_CHANGE_OR_CHROME_CRASH
+    metric = config.add_count_metric();
+    metric->set_metric_id(20150718L);
+    metric->set_what("PHOTO_PROCESS_STATE_CHANGE");
+    metric->mutable_bucket()->set_bucket_size_millis(60 * 1000L);
+    metric->set_condition("SCREEN_IS_ON");
+
+
+    LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_IS_ON");
+
+    SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
+    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+    simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int(
+            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+
+
+    eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_IS_OFF");
+
+    simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
+    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+    simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
+
+
+
+    LogEntryMatcher* procEventMatcher = config.add_log_entry_matcher();
+    procEventMatcher->set_name("PHOTO_CRASH");
+
+    SimpleLogEntryMatcher* simpleLogMatcher2 = procEventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogMatcher2->add_tag(1112 /*PROCESS_STATE_CHANGE*/);
+    KeyValueMatcher* keyValueMatcher = simpleLogMatcher2->add_key_value_matcher();
+    keyValueMatcher->mutable_key_matcher()->set_key(
+                1002 /*pkg*/);
+    keyValueMatcher->set_eq_string(
+            "com.google.android.apps.photos" /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+    keyValueMatcher = simpleLogMatcher2->add_key_value_matcher();
+    keyValueMatcher->mutable_key_matcher()->set_key(
+                                   1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+    keyValueMatcher->set_eq_int(2);
+
+
+    procEventMatcher = config.add_log_entry_matcher();
+    procEventMatcher->set_name("PHOTO_START");
+
+    simpleLogMatcher2 = procEventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogMatcher2->add_tag(1112 /*PROCESS_STATE_CHANGE*/);
+    keyValueMatcher = simpleLogMatcher2->add_key_value_matcher();
+    keyValueMatcher->mutable_key_matcher()->set_key(
+                1002 /*pkg*/);
+    keyValueMatcher->set_eq_string(
+            "com.google.android.apps.photos" /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+    keyValueMatcher = simpleLogMatcher2->add_key_value_matcher();
+    keyValueMatcher->mutable_key_matcher()->set_key(
+                                   1 /*STATE*/);
+    keyValueMatcher->set_eq_int(1);
+
+
+    procEventMatcher = config.add_log_entry_matcher();
+    procEventMatcher->set_name("PHOTO_PROCESS_STATE_CHANGE");
+    LogEntryMatcher_Combination* combinationMatcher = procEventMatcher->mutable_combination();
+    combinationMatcher->set_operation(LogicalOperation::OR);
+    combinationMatcher->add_matcher("PHOTO_START");
+    combinationMatcher->add_matcher("PHOTO_CRASH");
+
+
+    procEventMatcher = config.add_log_entry_matcher();
+    procEventMatcher->set_name("CHROME_CRASH");
+
+    simpleLogMatcher2 = procEventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogMatcher2->add_tag(1112 /*PROCESS_STATE_CHANGE*/);
+    keyValueMatcher = simpleLogMatcher2->add_key_value_matcher();
+    keyValueMatcher->mutable_key_matcher()->set_key(
+                1002 /*pkg*/);
+    keyValueMatcher->set_eq_string(
+            "com.android.chrome" /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+    keyValueMatcher = simpleLogMatcher2->add_key_value_matcher();
+    keyValueMatcher->mutable_key_matcher()->set_key(
+                                   1 /*STATE*/);
+    keyValueMatcher->set_eq_int(2);
+
+
+
+    procEventMatcher = config.add_log_entry_matcher();
+    procEventMatcher->set_name("PHOTO_CHANGE_OR_CHROME_CRASH");
+    combinationMatcher = procEventMatcher->mutable_combination();
+    combinationMatcher->set_operation(LogicalOperation::OR);
+    combinationMatcher->add_matcher("PHOTO_PROCESS_STATE_CHANGE");
+    combinationMatcher->add_matcher("CHROME_CRASH");
+
+
+
+    Condition* condition = config.add_condition();
+    condition->set_name("SCREEN_IS_ON");
+    SimpleCondition* simpleCondition = condition->mutable_simple_condition();
+    simpleCondition->set_start("SCREEN_IS_ON");
+    simpleCondition->set_stop("SCREEN_IS_OFF");
+
+
+    condition = config.add_condition();
+        condition->set_name("PHOTO_STARTED");
+
+        simpleCondition = condition->mutable_simple_condition();
+        simpleCondition->set_start("PHOTO_START");
+        simpleCondition->set_stop("PHOTO_CRASH");
+
+
+    condition = config.add_condition();
+    condition->set_name("SCREEN_IS_OFF");
+
+    simpleCondition = condition->mutable_simple_condition();
+    simpleCondition->set_start("SCREEN_IS_OFF");
+    simpleCondition->set_stop("SCREEN_IS_ON");
+
+
+    condition = config.add_condition();
+    condition->set_name("SCREEN_IS_EITHER_ON_OFF");
+
+    Condition_Combination* combination = condition->mutable_combination();
+    combination->set_operation(LogicalOperation::OR);
+    combination->add_condition("SCREEN_IS_ON");
+    combination->add_condition("SCREEN_IS_OFF");
+
+
+    condition = config.add_condition();
+    condition->set_name("SCREEN_IS_NEITHER_ON_OFF");
+
+    combination = condition->mutable_combination();
+    combination->set_operation(LogicalOperation::NOR);
+    combination->add_condition("SCREEN_IS_ON");
+    combination->add_condition("SCREEN_IS_OFF");
+
+    return config;
+}
+
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/parse_util.h b/cmds/statsd/src/stats_util.h
similarity index 90%
rename from cmds/statsd/src/parse_util.h
rename to cmds/statsd/src/stats_util.h
index 8b82e7b..25b9bba 100644
--- a/cmds/statsd/src/parse_util.h
+++ b/cmds/statsd/src/stats_util.h
@@ -20,6 +20,7 @@
 #include "LogReader.h"
 
 #include <log/logprint.h>
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 
 namespace android {
 namespace os {
@@ -29,6 +30,8 @@
 
 int getTagId(log_msg msg);
 
+StatsdConfig buildFakeConfig();
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 3e4ebaf..d7702cd 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -65,7 +65,8 @@
 
   message Combination {
     optional LogicalOperation operation = 1;
-    repeated LogEntryMatcher matcher = 2;
+
+    repeated string matcher = 2;
   }
   oneof contents {
     SimpleLogEntryMatcher simple_log_entry_matcher = 2;
@@ -122,6 +123,24 @@
   optional Bucket bucket = 5;
 }
 
+message DurationMetric {
+  optional int64 metric_id = 1;
+
+  enum AggregationType {
+    DURATION_SUM = 1;
+
+    DURATION_MAX_SPARSE = 2;
+    DURATION_MIN_SPARSE = 3;
+  }
+  optional AggregationType type = 2;
+
+  optional string predicate = 3;
+
+  repeated KeyMatcher dimension = 4;
+
+  optional Bucket bucket = 5;
+}
+
 message StatsdConfig {
   optional int64 config_id = 1;
 
diff --git a/cmds/statsd/tests/AnomalyMonitor_test.cpp b/cmds/statsd/tests/AnomalyMonitor_test.cpp
new file mode 100644
index 0000000..d5b6811
--- /dev/null
+++ b/cmds/statsd/tests/AnomalyMonitor_test.cpp
@@ -0,0 +1,66 @@
+// Copyright (C) 2017 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.
+
+#define LOG_TAG "statsd_test"
+
+#include "../src/AnomalyMonitor.h"
+
+#include <gtest/gtest.h>
+
+using namespace android::os::statsd;
+
+#ifdef __ANDROID__
+TEST(AnomalyMonitor, popSoonerThan) {
+    unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> set;
+    AnomalyMonitor am(2);
+
+    set = am.popSoonerThan(5);
+    EXPECT_TRUE(set.empty());
+
+    sp<const AnomalyAlarm> a = new AnomalyAlarm{10};
+    sp<const AnomalyAlarm> b = new AnomalyAlarm{20};
+    sp<const AnomalyAlarm> c = new AnomalyAlarm{20};
+    sp<const AnomalyAlarm> d = new AnomalyAlarm{30};
+    sp<const AnomalyAlarm> e = new AnomalyAlarm{40};
+    sp<const AnomalyAlarm> f = new AnomalyAlarm{50};
+
+    am.add(a);
+    am.add(b);
+    am.add(c);
+    am.add(d);
+    am.add(e);
+    am.add(f);
+
+    set = am.popSoonerThan(5);
+    EXPECT_TRUE(set.empty());
+
+    set = am.popSoonerThan(30);
+    EXPECT_EQ(4u, set.size());
+    EXPECT_EQ(1u, set.count(a));
+    EXPECT_EQ(1u, set.count(b));
+    EXPECT_EQ(1u, set.count(c));
+    EXPECT_EQ(1u, set.count(d));
+
+    set = am.popSoonerThan(60);
+    EXPECT_EQ(2u, set.size());
+    EXPECT_EQ(1u, set.count(e));
+    EXPECT_EQ(1u, set.count(f));
+
+    set = am.popSoonerThan(80);
+    EXPECT_EQ(0u, set.size());
+}
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/cmds/statsd/tests/ConditionTracker_test.cpp b/cmds/statsd/tests/ConditionTracker_test.cpp
new file mode 100644
index 0000000..f8b0fd0
--- /dev/null
+++ b/cmds/statsd/tests/ConditionTracker_test.cpp
@@ -0,0 +1,162 @@
+// Copyright (C) 2017 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.
+
+#define LOG_TAG "statsd_test"
+
+#include <gtest/gtest.h>
+#include "../src/condition/condition_util.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+
+#include <stdio.h>
+#include <vector>
+
+using namespace android::os::statsd;
+using std::vector;
+
+
+#ifdef __ANDROID__
+TEST(ConditionTrackerTest, TestUnknownCondition) {
+    LogicalOperation operation = LogicalOperation::AND;
+
+    vector<int> children;
+    children.push_back(0);
+    children.push_back(1);
+    children.push_back(2);
+
+    vector<ConditionState> conditionResults;
+    conditionResults.push_back(ConditionState::kUnknown);
+    conditionResults.push_back(ConditionState::kFalse);
+    conditionResults.push_back(ConditionState::kTrue);
+
+    EXPECT_EQ(evaluateCombinationCondition(children, operation, conditionResults),
+            ConditionState::kUnknown);
+}
+TEST(ConditionTrackerTest, TestAndCondition) {
+    // Set up the matcher
+    LogicalOperation operation = LogicalOperation::AND;
+
+    vector<int> children;
+    children.push_back(0);
+    children.push_back(1);
+    children.push_back(2);
+
+    vector<ConditionState> conditionResults;
+    conditionResults.push_back(ConditionState::kTrue);
+    conditionResults.push_back(ConditionState::kFalse);
+    conditionResults.push_back(ConditionState::kTrue);
+
+    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
+
+    conditionResults.clear();
+    conditionResults.push_back(ConditionState::kTrue);
+    conditionResults.push_back(ConditionState::kTrue);
+    conditionResults.push_back(ConditionState::kTrue);
+
+    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
+}
+
+TEST(ConditionTrackerTest, TestOrCondition) {
+    // Set up the matcher
+    LogicalOperation operation = LogicalOperation::OR;
+
+    vector<int> children;
+    children.push_back(0);
+    children.push_back(1);
+    children.push_back(2);
+
+    vector<ConditionState> conditionResults;
+    conditionResults.push_back(ConditionState::kTrue);
+    conditionResults.push_back(ConditionState::kFalse);
+    conditionResults.push_back(ConditionState::kTrue);
+
+    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
+
+    conditionResults.clear();
+    conditionResults.push_back(ConditionState::kFalse);
+    conditionResults.push_back(ConditionState::kFalse);
+    conditionResults.push_back(ConditionState::kFalse);
+
+    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
+}
+
+TEST(ConditionTrackerTest, TestNotCondition) {
+    // Set up the matcher
+    LogicalOperation operation = LogicalOperation::NOT;
+
+    vector<int> children;
+    children.push_back(0);
+
+    vector<ConditionState> conditionResults;
+    conditionResults.push_back(ConditionState::kTrue);
+
+    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
+
+    conditionResults.clear();
+    conditionResults.push_back(ConditionState::kFalse);
+    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
+}
+
+TEST(ConditionTrackerTest, TestNandCondition) {
+    // Set up the matcher
+    LogicalOperation operation = LogicalOperation::NAND;
+
+    vector<int> children;
+    children.push_back(0);
+    children.push_back(1);
+
+    vector<ConditionState> conditionResults;
+    conditionResults.push_back(ConditionState::kTrue);
+    conditionResults.push_back(ConditionState::kFalse);
+
+    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
+
+    conditionResults.clear();
+    conditionResults.push_back(ConditionState::kFalse);
+    conditionResults.push_back(ConditionState::kFalse);
+    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
+
+    conditionResults.clear();
+    conditionResults.push_back(ConditionState::kTrue);
+    conditionResults.push_back(ConditionState::kTrue);
+    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
+}
+
+TEST(ConditionTrackerTest, TestNorCondition) {
+    // Set up the matcher
+    LogicalOperation operation = LogicalOperation::NOR;
+
+    vector<int> children;
+    children.push_back(0);
+    children.push_back(1);
+
+    vector<ConditionState> conditionResults;
+    conditionResults.push_back(ConditionState::kTrue);
+    conditionResults.push_back(ConditionState::kFalse);
+
+    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
+
+    conditionResults.clear();
+    conditionResults.push_back(ConditionState::kFalse);
+    conditionResults.push_back(ConditionState::kFalse);
+    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
+
+    conditionResults.clear();
+    conditionResults.push_back(ConditionState::kTrue);
+    conditionResults.push_back(ConditionState::kTrue);
+    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
+}
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
index 473704a..6069801 100644
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp
@@ -18,14 +18,15 @@
 #include <log/log_event_list.h>
 #include <log/log_read.h>
 #include <log/logprint.h>
-#include "../src/matchers/LogEntryMatcherManager.h"
-#include "../src/parse_util.h"
+#include "../src/matchers/matcher_util.h"
+#include "../src/stats_util.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 
 #include <stdio.h>
 
 using namespace android::os::statsd;
 using std::unordered_map;
+using std::vector;
 
 const int kTagIdWakelock = 123;
 const int kKeyIdState = 45;
@@ -41,7 +42,7 @@
     LogEventWrapper wrapper;
     wrapper.tagId = kTagIdWakelock;
 
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
 }
 
 TEST(LogEntryMatcherTest, TestBoolMatcher) {
@@ -57,13 +58,13 @@
 
     keyValue->set_eq_bool(true);
     wrapper.boolMap[kKeyIdState] = true;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
 
     keyValue->set_eq_bool(false);
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
 
-    wrapper.boolMap[kTagIdWakelock] = false;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    wrapper.boolMap[kKeyIdState] = false;
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
 }
 
 TEST(LogEntryMatcherTest, TestStringMatcher) {
@@ -80,7 +81,7 @@
 
     wrapper.strMap[kKeyIdState] = "wakelock_name";
 
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
 }
 
 TEST(LogEntryMatcherTest, TestIntComparisonMatcher) {
@@ -96,19 +97,19 @@
 
     keyValue->set_lt_int(10);
     wrapper.intMap[kKeyIdState] = 11;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.intMap[kKeyIdState] = 10;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.intMap[kKeyIdState] = 9;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
 
     keyValue->set_gt_int(10);
     wrapper.intMap[kKeyIdState] = 11;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.intMap[kKeyIdState] = 10;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.intMap[kKeyIdState] = 9;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
 }
 
 TEST(LogEntryMatcherTest, TestIntWithEqualityComparisonMatcher) {
@@ -124,19 +125,19 @@
 
     keyValue->set_lte_int(10);
     wrapper.intMap[kKeyIdState] = 11;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.intMap[kKeyIdState] = 10;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.intMap[kKeyIdState] = 9;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
 
     keyValue->set_gte_int(10);
     wrapper.intMap[kKeyIdState] = 11;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.intMap[kKeyIdState] = 10;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.intMap[kKeyIdState] = 9;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
 }
 
 TEST(LogEntryMatcherTest, TestFloatComparisonMatcher) {
@@ -152,15 +153,15 @@
 
     keyValue->set_lt_float(10.0);
     wrapper.floatMap[kKeyIdState] = 10.1;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.floatMap[kKeyIdState] = 9.9;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
 
     keyValue->set_gt_float(10.0);
     wrapper.floatMap[kKeyIdState] = 10.1;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
     wrapper.floatMap[kKeyIdState] = 9.9;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
 }
 
 // Helper for the composite matchers.
@@ -173,141 +174,117 @@
 
 TEST(LogEntryMatcherTest, TestAndMatcher) {
     // Set up the matcher
-    LogEntryMatcher matcher;
-    auto combination = matcher.mutable_combination();
-    combination->set_operation(LogicalOperation::AND);
+    LogicalOperation operation = LogicalOperation::AND;
 
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-                     kTagIdWakelock, kKeyIdState, 3);
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-                     kTagIdWakelock, kKeyIdPackageVersion, 4);
+    vector<int> children;
+    children.push_back(0);
+    children.push_back(1);
+    children.push_back(2);
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    vector<MatchingState> matcherResults;
+    matcherResults.push_back(MatchingState::kMatched);
+    matcherResults.push_back(MatchingState::kNotMatched);
+    matcherResults.push_back(MatchingState::kMatched);
 
-    wrapper.intMap[1003] = 4;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap.clear();
-    wrapper.intMap[1] = 3;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap.clear();
-    wrapper.intMap[1] = 3;
-    wrapper.intMap[1003] = 4;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
+
+    matcherResults.clear();
+    matcherResults.push_back(MatchingState::kMatched);
+    matcherResults.push_back(MatchingState::kMatched);
+    matcherResults.push_back(MatchingState::kMatched);
+
+    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
 }
 
 TEST(LogEntryMatcherTest, TestOrMatcher) {
     // Set up the matcher
-    LogEntryMatcher matcher;
-    auto combination = matcher.mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
+    LogicalOperation operation = LogicalOperation::OR;
 
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-        kTagIdWakelock, kKeyIdState, 3);
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-        kTagIdWakelock, kKeyIdPackageVersion, 4);
+    vector<int> children;
+    children.push_back(0);
+    children.push_back(1);
+    children.push_back(2);
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    vector<MatchingState> matcherResults;
+    matcherResults.push_back(MatchingState::kMatched);
+    matcherResults.push_back(MatchingState::kNotMatched);
+    matcherResults.push_back(MatchingState::kMatched);
 
-    // Don't set any key-value pairs.
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap[1003] = 4;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap.clear();
-    wrapper.intMap[1] = 3;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap.clear();
-    wrapper.intMap[1] = 3;
-    wrapper.intMap[1003] = 4;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
+
+    matcherResults.clear();
+    matcherResults.push_back(MatchingState::kNotMatched);
+    matcherResults.push_back(MatchingState::kNotMatched);
+    matcherResults.push_back(MatchingState::kNotMatched);
+
+    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
 }
 
 TEST(LogEntryMatcherTest, TestNotMatcher) {
     // Set up the matcher
-    LogEntryMatcher matcher;
-    auto combination = matcher.mutable_combination();
-    combination->set_operation(LogicalOperation::NOT);
+    LogicalOperation operation = LogicalOperation::NOT;
 
-    // Define first simpleMatcher
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-        kTagIdWakelock, kKeyIdState, 3);
+    vector<int> children;
+    children.push_back(0);
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    vector<MatchingState> matcherResults;
+    matcherResults.push_back(MatchingState::kMatched);
 
-    // Don't set any key-value pairs.
-    wrapper.intMap[kKeyIdState] = 3;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
+
+    matcherResults.clear();
+    matcherResults.push_back(MatchingState::kNotMatched);
+    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
 }
 
-TEST(LogEntryMatcherTest, TestNANDMatcher) {
+TEST(LogEntryMatcherTest, TestNandMatcher) {
     // Set up the matcher
-    LogEntryMatcher matcher;
-    auto combination = matcher.mutable_combination();
-    combination->set_operation(LogicalOperation::NAND);
+    LogicalOperation operation = LogicalOperation::NAND;
 
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-        kTagIdWakelock, kKeyIdState, 3);
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-        kTagIdWakelock, kKeyIdPackageVersion, 4);
+    vector<int> children;
+    children.push_back(0);
+    children.push_back(1);
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    vector<MatchingState> matcherResults;
+    matcherResults.push_back(MatchingState::kMatched);
+    matcherResults.push_back(MatchingState::kNotMatched);
 
-    // Don't set any key-value pairs.
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 3;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap[kKeyIdPackageVersion] = 4;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
+
+    matcherResults.clear();
+    matcherResults.push_back(MatchingState::kNotMatched);
+    matcherResults.push_back(MatchingState::kNotMatched);
+    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
+
+    matcherResults.clear();
+    matcherResults.push_back(MatchingState::kMatched);
+    matcherResults.push_back(MatchingState::kMatched);
+    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
 }
 
-TEST(LogEntryMatcherTest, TestNORMatcher) {
+TEST(LogEntryMatcherTest, TestNorMatcher) {
     // Set up the matcher
-    LogEntryMatcher matcher;
-    auto combination = matcher.mutable_combination();
-    combination->set_operation(LogicalOperation::NOR);
+    LogicalOperation operation = LogicalOperation::NOR;
 
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-        kTagIdWakelock, kKeyIdState, 3);
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-        kTagIdWakelock, kKeyIdPackageVersion, 4);
+    vector<int> children;
+    children.push_back(0);
+    children.push_back(1);
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    vector<MatchingState> matcherResults;
+    matcherResults.push_back(MatchingState::kMatched);
+    matcherResults.push_back(MatchingState::kNotMatched);
 
-    // Don't set any key-value pairs.
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 3;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap[kKeyIdPackageVersion] = 4;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
-}
+    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
 
-// Tests that a NOT on top of AND is the same as NAND
-TEST(LogEntryMatcherTest, TestMultipleLayerMatcher) {
-    LogEntryMatcher matcher;
-    auto not_combination = matcher.mutable_combination();
-    not_combination->set_operation(LogicalOperation::NOT);
+    matcherResults.clear();
+    matcherResults.push_back(MatchingState::kNotMatched);
+    matcherResults.push_back(MatchingState::kNotMatched);
+    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
 
-    // Now add the AND
-    auto combination = not_combination->add_matcher()->mutable_combination();
-    combination->set_operation(LogicalOperation::AND);
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-        kTagIdWakelock, kKeyIdState, 3);
-    addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
-        kTagIdWakelock, kKeyIdPackageVersion, 4);
-
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
-
-    // Don't set any key-value pairs.
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 3;
-    EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, wrapper));
-    wrapper.intMap[kKeyIdPackageVersion] = 4;
-    EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, wrapper));
+    matcherResults.clear();
+    matcherResults.push_back(MatchingState::kMatched);
+    matcherResults.push_back(MatchingState::kMatched);
+    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
 }
 
 #else
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
new file mode 100644
index 0000000..673c156
--- /dev/null
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -0,0 +1,231 @@
+// Copyright (C) 2017 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.
+
+#define LOG_TAG "statsd_test"
+
+#include <gtest/gtest.h>
+#include "../src/condition/ConditionTracker.h"
+#include "../src/matchers/LogMatchingTracker.h"
+#include "../src/metrics/CountMetricProducer.h"
+#include "../src/metrics/MetricProducer.h"
+#include "../src/metrics/metrics_manager_util.h"
+
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+
+#include <stdio.h>
+#include <set>
+#include <unordered_map>
+#include <vector>
+
+using namespace android::os::statsd;
+using android::sp;
+using std::set;
+using std::unordered_map;
+using std::vector;
+
+#ifdef __ANDROID__
+
+// TODO: ADD MORE TEST CASES.
+
+StatsdConfig buildGoodConfig() {
+    StatsdConfig config;
+    config.set_config_id(12345L);
+
+    LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_IS_ON");
+
+    SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
+    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+    simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int(
+            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+    eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_IS_OFF");
+
+    simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
+    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+    simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
+
+    eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_ON_OR_OFF");
+
+    LogEntryMatcher_Combination* combination = eventMatcher->mutable_combination();
+    combination->set_operation(LogicalOperation::OR);
+    combination->add_matcher("SCREEN_IS_ON");
+    combination->add_matcher("SCREEN_IS_OFF");
+
+    return config;
+}
+
+StatsdConfig buildCircleMatchers() {
+    StatsdConfig config;
+    config.set_config_id(12345L);
+
+    LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_IS_ON");
+
+    SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
+    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+    simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int(
+            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+    eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_ON_OR_OFF");
+
+    LogEntryMatcher_Combination* combination = eventMatcher->mutable_combination();
+    combination->set_operation(LogicalOperation::OR);
+    combination->add_matcher("SCREEN_IS_ON");
+    // Circle dependency
+    combination->add_matcher("SCREEN_ON_OR_OFF");
+
+    return config;
+}
+
+StatsdConfig buildMissingMatchers() {
+    StatsdConfig config;
+    config.set_config_id(12345L);
+
+    LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_IS_ON");
+
+    SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
+    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+    simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int(
+            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+    eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_ON_OR_OFF");
+
+    LogEntryMatcher_Combination* combination = eventMatcher->mutable_combination();
+    combination->set_operation(LogicalOperation::OR);
+    combination->add_matcher("SCREEN_IS_ON");
+    // undefined matcher
+    combination->add_matcher("ABC");
+
+    return config;
+}
+
+StatsdConfig buildCircleConditions() {
+    StatsdConfig config;
+    config.set_config_id(12345L);
+
+    LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_IS_ON");
+
+    SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
+    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+    simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int(
+            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+    eventMatcher = config.add_log_entry_matcher();
+    eventMatcher->set_name("SCREEN_IS_OFF");
+
+    simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
+    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+    simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int(
+            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
+
+    Condition* condition = config.add_condition();
+    condition->set_name("SCREEN_IS_ON");
+    SimpleCondition* simpleCondition = condition->mutable_simple_condition();
+    simpleCondition->set_start("SCREEN_IS_ON");
+    simpleCondition->set_stop("SCREEN_IS_OFF");
+
+    condition = config.add_condition();
+    condition->set_name("SCREEN_IS_EITHER_ON_OFF");
+
+    Condition_Combination* combination = condition->mutable_combination();
+    combination->set_operation(LogicalOperation::OR);
+    combination->add_condition("SCREEN_IS_ON");
+    combination->add_condition("SCREEN_IS_EITHER_ON_OFF");
+
+    return config;
+}
+
+TEST(MetricsManagerTest, TestGoodConfig) {
+    StatsdConfig config = buildGoodConfig();
+    set<int> allTagIds;
+    vector<sp<LogMatchingTracker>> allLogEntryMatchers;
+    vector<sp<ConditionTracker>> allConditionTrackers;
+    vector<sp<MetricProducer>> allMetricProducers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+
+    EXPECT_TRUE(initStatsdConfig(config, allTagIds, allLogEntryMatchers, allConditionTrackers,
+                                 allMetricProducers, conditionToMetricMap, trackerToMetricMap,
+                                 trackerToConditionMap));
+}
+
+TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
+    StatsdConfig config = buildCircleMatchers();
+    set<int> allTagIds;
+    vector<sp<LogMatchingTracker>> allLogEntryMatchers;
+    vector<sp<ConditionTracker>> allConditionTrackers;
+    vector<sp<MetricProducer>> allMetricProducers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+
+    EXPECT_FALSE(initStatsdConfig(config, allTagIds, allLogEntryMatchers, allConditionTrackers,
+                                  allMetricProducers, conditionToMetricMap, trackerToMetricMap,
+                                  trackerToConditionMap));
+}
+
+TEST(MetricsManagerTest, TestMissingMatchers) {
+    StatsdConfig config = buildMissingMatchers();
+    set<int> allTagIds;
+    vector<sp<LogMatchingTracker>> allLogEntryMatchers;
+    vector<sp<ConditionTracker>> allConditionTrackers;
+    vector<sp<MetricProducer>> allMetricProducers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+
+    EXPECT_FALSE(initStatsdConfig(config, allTagIds, allLogEntryMatchers, allConditionTrackers,
+                                  allMetricProducers, conditionToMetricMap, trackerToMetricMap,
+                                  trackerToConditionMap));
+}
+
+TEST(MetricsManagerTest, TestCircleConditionDependency) {
+    StatsdConfig config = buildCircleConditions();
+    set<int> allTagIds;
+    vector<sp<LogMatchingTracker>> allLogEntryMatchers;
+    vector<sp<ConditionTracker>> allConditionTrackers;
+    vector<sp<MetricProducer>> allMetricProducers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+
+    EXPECT_FALSE(initStatsdConfig(config, allTagIds, allLogEntryMatchers, allConditionTrackers,
+                                  allMetricProducers, conditionToMetricMap, trackerToMetricMap,
+                                  trackerToConditionMap));
+}
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
new file mode 100644
index 0000000..b6f1449
--- /dev/null
+++ b/cmds/statsd/tests/UidMap_test.cpp
@@ -0,0 +1,69 @@
+// Copyright (C) 2017 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.
+
+#define LOG_TAG "statsd_test"
+
+#include <gtest/gtest.h>
+#include "../src/UidMap.h"
+#include <stdio.h>
+
+using namespace android;
+using namespace android::os::statsd;
+
+#ifdef __ANDROID__
+const string kApp1 = "app1.sharing.1";
+const string kApp2 = "app2.sharing.1";
+
+TEST(UidMapTest, TestMatching) {
+    UidMap m;
+    vector<int32_t> uids;
+    vector<int32_t> versions;
+    vector<String16> apps;
+
+    uids.push_back(1000);
+    uids.push_back(1000);
+    apps.push_back(String16(kApp1.c_str()));
+    apps.push_back(String16(kApp2.c_str()));
+    versions.push_back(4);
+    versions.push_back(5);
+    m.updateMap(uids, versions, apps);
+    EXPECT_TRUE(m.hasApp(1000, kApp1));
+    EXPECT_TRUE(m.hasApp(1000, kApp2));
+    EXPECT_FALSE(m.hasApp(1000, "not.app"));
+}
+
+TEST(UidMapTest, TestAddAndRemove) {
+    UidMap m;
+    vector<int32_t> uids;
+    vector<int32_t> versions;
+    vector<String16> apps;
+
+    uids.push_back(1000);
+    uids.push_back(1000);
+    apps.push_back(String16(kApp1.c_str()));
+    apps.push_back(String16(kApp2.c_str()));
+    versions.push_back(4);
+    versions.push_back(5);
+    m.updateMap(uids, versions, apps);
+
+    m.updateApp(String16(kApp1.c_str()), 1000, 40);
+    EXPECT_EQ(40, m.getAppVersion(1000, kApp1));
+
+    m.removeApp(String16(kApp1.c_str()), 1000);
+    EXPECT_FALSE(m.hasApp(1000, kApp1));
+    EXPECT_TRUE(m.hasApp(1000, kApp2));
+}
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
\ No newline at end of file
diff --git a/cmds/statsd/tests/indexed_priority_queue_test.cpp b/cmds/statsd/tests/indexed_priority_queue_test.cpp
index e4d4d25..74a482e 100644
--- a/cmds/statsd/tests/indexed_priority_queue_test.cpp
+++ b/cmds/statsd/tests/indexed_priority_queue_test.cpp
@@ -182,6 +182,40 @@
     EXPECT_FALSE(ipq.contains(nullptr));
 }
 
+TEST(indexed_priority_queue, pop) {
+    indexed_priority_queue<AATest, AATest::Smaller> ipq;
+    sp<const AATest> a = new AATest{1};
+    sp<const AATest> b = new AATest{2};
+    sp<const AATest> c = new AATest{3};
+
+    ipq.push(c);
+    ipq.push(b);
+    ipq.push(a);
+    EXPECT_EQ(3u, ipq.size());
+
+    ipq.pop();
+    EXPECT_EQ(2u, ipq.size());
+    EXPECT_FALSE(ipq.contains(a));
+    EXPECT_TRUE(ipq.contains(b));
+    EXPECT_TRUE(ipq.contains(c));
+
+    ipq.pop();
+    EXPECT_EQ(1u, ipq.size());
+    EXPECT_FALSE(ipq.contains(a));
+    EXPECT_FALSE(ipq.contains(b));
+    EXPECT_TRUE(ipq.contains(c));
+
+    ipq.pop();
+    EXPECT_EQ(0u, ipq.size());
+    EXPECT_FALSE(ipq.contains(a));
+    EXPECT_FALSE(ipq.contains(b));
+    EXPECT_FALSE(ipq.contains(c));
+    EXPECT_TRUE(ipq.empty());
+
+    ipq.pop(); // pop an empty queue
+    EXPECT_TRUE(ipq.empty());
+}
+
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/config/compiled-classes-phone b/config/compiled-classes-phone
index 42e6ecf..f32c0d6 100644
--- a/config/compiled-classes-phone
+++ b/config/compiled-classes-phone
@@ -3269,6 +3269,7 @@
 android.os.Parcel
 android.os.Parcel$1
 android.os.Parcel$2
+android.os.Parcel$ReadWriteHelper
 android.os.ParcelFileDescriptor
 android.os.ParcelFileDescriptor$1
 android.os.ParcelFileDescriptor$2
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e0ac911..252959a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -542,9 +542,9 @@
  * <ul>
  *     <li> <p>When creating a new document, the backing database entry or file for
  *             it is created immediately.  For example, if the user chooses to write
- *             a new e-mail, a new entry for that e-mail is created as soon as they
+ *             a new email, a new entry for that email is created as soon as they
  *             start entering data, so that if they go to any other activity after
- *             that point this e-mail will now appear in the list of drafts.</p>
+ *             that point this email will now appear in the list of drafts.</p>
  *     <li> <p>When an activity's <code>onPause()</code> method is called, it should
  *             commit to the backing content provider or file any changes the user
  *             has made.  This ensures that those changes will be seen by any other
@@ -1879,7 +1879,7 @@
 
         if (isFinishing()) {
             if (mAutoFillResetNeeded) {
-                getAutofillManager().commit();
+                getAutofillManager().onActivityFinished();
             } else if (mIntent != null
                     && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {
                 // Activity was launched when user tapped a link in the Autofill Save UI - since
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 5e61727..027e811 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -16,13 +16,6 @@
 
 package android.app;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-
 import android.Manifest;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -670,138 +663,6 @@
         /** Invalid stack ID. */
         public static final int INVALID_STACK_ID = -1;
 
-        /** First static stack ID.
-         * @hide */
-        private  static final int FIRST_STATIC_STACK_ID = 0;
-
-        /** ID of stack where fullscreen activities are normally launched into.
-         * @hide */
-        public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
-
-        /** ID of stack where freeform/resized activities are normally launched into.
-         * @hide */
-        public static final int FREEFORM_WORKSPACE_STACK_ID = FULLSCREEN_WORKSPACE_STACK_ID + 1;
-
-        /** ID of stack that occupies a dedicated region of the screen.
-         * @hide */
-        public static final int DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID + 1;
-
-        /** ID of stack that always on top (always visible) when it exist.
-         * @hide */
-        public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1;
-
-        /** Last static stack stack ID.
-         * @hide */
-        private static final int LAST_STATIC_STACK_ID = PINNED_STACK_ID;
-
-        /** Start of ID range used by stacks that are created dynamically.
-         * @hide */
-        public static final int FIRST_DYNAMIC_STACK_ID = LAST_STATIC_STACK_ID + 1;
-
-        // TODO: Figure-out a way to remove this.
-        /** @hide */
-        public static boolean isStaticStack(int stackId) {
-            return stackId >= FIRST_STATIC_STACK_ID && stackId <= LAST_STATIC_STACK_ID;
-        }
-
-        // TODO: It seems this mostly means a stack on a secondary display now. Need to see if
-        // there are other meanings. If not why not just use information from the display?
-        /** @hide */
-        public static boolean isDynamicStack(int stackId) {
-            return stackId >= FIRST_DYNAMIC_STACK_ID;
-        }
-
-        /**
-         * Returns true if we try to maintain focus in the current stack when the top activity
-         * finishes.
-         * @hide
-         */
-        // TODO: Figure-out a way to remove. Probably isn't needed in the new world...
-        public static boolean keepFocusInStackIfPossible(int stackId) {
-            return stackId == FREEFORM_WORKSPACE_STACK_ID
-                    || stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID;
-        }
-
-        /**
-         * Returns true if the windows of tasks being moved to the target stack from the source
-         * stack should be replaced, meaning that window manager will keep the old window around
-         * until the new is ready.
-         * @hide
-         */
-        public static boolean replaceWindowsOnTaskMove(int sourceStackId, int targetStackId) {
-            return sourceStackId == FREEFORM_WORKSPACE_STACK_ID
-                    || targetStackId == FREEFORM_WORKSPACE_STACK_ID;
-        }
-
-        /**
-         * Returns true if the top task in the task is allowed to return home when finished and
-         * there are other tasks in the stack.
-         * @hide
-         */
-        public static boolean allowTopTaskToReturnHome(int stackId) {
-            return stackId != PINNED_STACK_ID;
-        }
-
-        /**
-         * Returns true if the stack should be resized to match the bounds specified by
-         * {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack.
-         * @hide
-         */
-        public static boolean resizeStackWithLaunchBounds(int stackId) {
-            return stackId == PINNED_STACK_ID;
-        }
-
-        /**
-         * Returns true if a window from the specified stack with {@param stackId} are normally
-         * fullscreen, i. e. they can become the top opaque fullscreen window, meaning that it
-         * controls system bars, lockscreen occluded/dismissing state, screen rotation animation,
-         * etc.
-         * @hide
-         */
-        // TODO: What about the other side of docked stack if we move this to WindowConfiguration?
-        public static boolean normallyFullscreenWindows(int stackId) {
-            return stackId != PINNED_STACK_ID && stackId != FREEFORM_WORKSPACE_STACK_ID
-                    && stackId != DOCKED_STACK_ID;
-        }
-
-        /** Returns the stack id for the input windowing mode.
-         * @hide */
-        // TODO: To be removed once we are not using stack id for stuff...
-        public static int getStackIdForWindowingMode(int windowingMode) {
-            switch (windowingMode) {
-                case WINDOWING_MODE_PINNED: return PINNED_STACK_ID;
-                case WINDOWING_MODE_FREEFORM: return FREEFORM_WORKSPACE_STACK_ID;
-                case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: return DOCKED_STACK_ID;
-                case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: return FULLSCREEN_WORKSPACE_STACK_ID;
-                case WINDOWING_MODE_FULLSCREEN: return FULLSCREEN_WORKSPACE_STACK_ID;
-                default: return INVALID_STACK_ID;
-            }
-        }
-
-        /** Returns the windowing mode that should be used for this input stack id.
-         * @hide */
-        // TODO: To be removed once we are not using stack id for stuff...
-        public static int getWindowingModeForStackId(int stackId, boolean inSplitScreenMode) {
-            final int windowingMode;
-            switch (stackId) {
-                case FULLSCREEN_WORKSPACE_STACK_ID:
-                    windowingMode = inSplitScreenMode
-                            ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY : WINDOWING_MODE_FULLSCREEN;
-                    break;
-                case PINNED_STACK_ID:
-                    windowingMode = WINDOWING_MODE_PINNED;
-                    break;
-                case DOCKED_STACK_ID:
-                    windowingMode = WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-                    break;
-                case FREEFORM_WORKSPACE_STACK_ID:
-                    windowingMode = WINDOWING_MODE_FREEFORM;
-                    break;
-                default :
-                    windowingMode = WINDOWING_MODE_UNDEFINED;
-            }
-            return windowingMode;
-        }
     }
 
     /**
@@ -1571,7 +1432,6 @@
             }
             dest.writeInt(stackId);
             dest.writeInt(userId);
-            dest.writeLong(firstActiveTime);
             dest.writeLong(lastActiveTime);
             dest.writeInt(affiliatedTaskId);
             dest.writeInt(affiliatedTaskColor);
@@ -1600,7 +1460,6 @@
                     TaskDescription.CREATOR.createFromParcel(source) : null;
             stackId = source.readInt();
             userId = source.readInt();
-            firstActiveTime = source.readLong();
             lastActiveTime = source.readLong();
             affiliatedTaskId = source.readInt();
             affiliatedTaskColor = source.readInt();
@@ -1643,31 +1502,6 @@
     public static final int RECENT_IGNORE_UNAVAILABLE = 0x0002;
 
     /**
-     * Provides a list that contains recent tasks for all
-     * profiles of a user.
-     * @hide
-     */
-    public static final int RECENT_INCLUDE_PROFILES = 0x0004;
-
-    /**
-     * Ignores all tasks that are on the home stack.
-     * @hide
-     */
-    public static final int RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS = 0x0008;
-
-    /**
-     * Ignores the top task in the docked stack.
-     * @hide
-     */
-    public static final int RECENT_INGORE_DOCKED_STACK_TOP_TASK = 0x0010;
-
-    /**
-     * Ignores all tasks that are on the pinned stack.
-     * @hide
-     */
-    public static final int RECENT_INGORE_PINNED_STACK_TASKS = 0x0020;
-
-    /**
      * <p></p>Return a list of the tasks that the user has recently launched, with
      * the most recent being first and older ones after in order.
      *
@@ -1702,33 +1536,7 @@
     public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
             throws SecurityException {
         try {
-            return getService().getRecentTasks(maxNum,
-                    flags, UserHandle.myUserId()).getList();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Same as {@link #getRecentTasks(int, int)} but returns the recent tasks for a
-     * specific user. It requires holding
-     * the {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission.
-     * @param maxNum The maximum number of entries to return in the list.  The
-     * actual number returned may be smaller, depending on how many tasks the
-     * user has started and the maximum number the system can remember.
-     * @param flags Information about what to return.  May be any combination
-     * of {@link #RECENT_WITH_EXCLUDED} and {@link #RECENT_IGNORE_UNAVAILABLE}.
-     *
-     * @return Returns a list of RecentTaskInfo records describing each of
-     * the recent tasks. Most recently activated tasks go first.
-     *
-     * @hide
-     */
-    public List<RecentTaskInfo> getRecentTasksForUser(int maxNum, int flags, int userId)
-            throws SecurityException {
-        try {
-            return getService().getRecentTasks(maxNum,
-                    flags, userId).getList();
+            return getService().getRecentTasks(maxNum, flags, UserHandle.myUserId()).getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2021,22 +1829,6 @@
     }
 
     /**
-     * Completely remove the given task.
-     *
-     * @param taskId Identifier of the task to be removed.
-     * @return Returns true if the given task was found and removed.
-     *
-     * @hide
-     */
-    public boolean removeTask(int taskId) throws SecurityException {
-        try {
-            return getService().removeTask(taskId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Sets the windowing mode for a specific task. Only works on tasks of type
      * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}
      * @param taskId The id of the task to set the windowing mode for.
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index a68c3a5..b62e4c2 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -17,13 +17,13 @@
 package android.app;
 
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.Display.INVALID_DISPLAY;
 
 import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -159,6 +159,12 @@
     private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
 
     /**
+     * Whether the activity should be launched into LockTask mode.
+     * @see #setLockTaskMode(boolean)
+     */
+    private static final String KEY_LOCK_TASK_MODE = "android:activity.lockTaskMode";
+
+    /**
      * The display id the activity should be launched into.
      * @see #setLaunchDisplayId(int)
      * @hide
@@ -279,6 +285,7 @@
     private int mResultCode;
     private int mExitCoordinatorIndex;
     private PendingIntent mUsageTimeReport;
+    private boolean mLockTaskMode = false;
     private int mLaunchDisplayId = INVALID_DISPLAY;
     @WindowConfiguration.WindowingMode
     private int mLaunchWindowingMode = WINDOWING_MODE_UNDEFINED;
@@ -870,6 +877,7 @@
                 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
                 break;
         }
+        mLockTaskMode = opts.getBoolean(KEY_LOCK_TASK_MODE, false);
         mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY);
         mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED);
         mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED);
@@ -1056,6 +1064,37 @@
     }
 
     /**
+     * Gets whether the activity is to be launched into LockTask mode.
+     * @return {@code true} if the activity is to be launched into LockTask mode.
+     * @see Activity#startLockTask()
+     * @see android.app.admin.DevicePolicyManager#setLockTaskPackages(ComponentName, String[])
+     */
+    public boolean getLockTaskMode() {
+        return mLockTaskMode;
+    }
+
+    /**
+     * Sets whether the activity is to be launched into LockTask mode.
+     *
+     * Use this option to start an activity in LockTask mode. Note that only apps permitted by
+     * {@link android.app.admin.DevicePolicyManager} can run in LockTask mode. Therefore, if
+     * {@link android.app.admin.DevicePolicyManager#isLockTaskPermitted(String)} returns
+     * {@code false} for the package of the target activity, a {@link SecurityException} will be
+     * thrown during {@link Context#startActivity(Intent, Bundle)}.
+     *
+     * Defaults to {@code false} if not set.
+     *
+     * @param lockTaskMode {@code true} if the activity is to be launched into LockTask mode.
+     * @return {@code this} {@link ActivityOptions} instance.
+     * @see Activity#startLockTask()
+     * @see android.app.admin.DevicePolicyManager#setLockTaskPackages(ComponentName, String[])
+     */
+    public ActivityOptions setLockTaskMode(boolean lockTaskMode) {
+        mLockTaskMode = lockTaskMode;
+        return this;
+    }
+
+    /**
      * Gets the id of the display where activity should be launched.
      * @return The id of the display where activity should be launched,
      *         {@link android.view.Display#INVALID_DISPLAY} if not set.
@@ -1248,6 +1287,7 @@
                 mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex;
                 break;
         }
+        mLockTaskMode = otherOptions.mLockTaskMode;
         mAnimSpecs = otherOptions.mAnimSpecs;
         mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
         mSpecsFuture = otherOptions.mSpecsFuture;
@@ -1322,6 +1362,7 @@
                 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
                 break;
         }
+        b.putBoolean(KEY_LOCK_TASK_MODE, mLockTaskMode);
         b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
         b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode);
         b.putInt(KEY_LAUNCH_ACTIVITY_TYPE, mLaunchActivityType);
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index f039516..117854a 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -178,8 +178,8 @@
      * SIGUSR1 is delivered. All others are ignored.
      */
     void signalPersistentProcesses(int signal);
-    ParceledListSlice getRecentTasks(int maxNum,
-            int flags, int userId);
+
+    ParceledListSlice getRecentTasks(int maxNum, int flags, int userId);
     oneway void serviceDoneExecuting(in IBinder token, int type, int startId, int res);
     oneway void activityDestroyed(in IBinder token);
     IIntentSender getIntentSender(int type, in String packageName, in IBinder token,
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 54f74b1..1fe2900 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -387,8 +387,6 @@
      * such as the Home key and the right soft keys, don't work.
      *
      * @return true if in keyguard restricted input mode.
-     *
-     * @see android.view.WindowManagerPolicy#inKeyguardRestrictedKeyInputMode
      */
     public boolean inKeyguardRestrictedInputMode() {
         try {
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 47063f0..c06ad3f 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -32,6 +32,8 @@
 
 import com.android.internal.util.Preconditions;
 
+import com.android.internal.util.Preconditions;
+
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.xmlpull.v1.XmlPullParser;
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index eb52cb7..a52dc1e 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -934,8 +934,14 @@
         public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
         /** Calls from repeat callers are prioritized. */
         public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
+        /** Alarms are prioritized */
+        public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5;
+        /** Media, system, game (catch-all for non-never suppressible sounds) are prioritized */
+        public static final int PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER = 1 << 6;
 
         private static final int[] ALL_PRIORITY_CATEGORIES = {
+            PRIORITY_CATEGORY_ALARMS,
+            PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER,
             PRIORITY_CATEGORY_REMINDERS,
             PRIORITY_CATEGORY_EVENTS,
             PRIORITY_CATEGORY_MESSAGES,
@@ -1135,6 +1141,9 @@
                 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
                 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
                 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
+                case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
+                case PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER:
+                    return "PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER";
                 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
             }
         }
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 8987bc0..23c4166 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -73,15 +73,16 @@
     public static final int DISABLE2_QUICK_SETTINGS = 1;
     public static final int DISABLE2_SYSTEM_ICONS = 1 << 1;
     public static final int DISABLE2_NOTIFICATION_SHADE = 1 << 2;
+    public static final int DISABLE2_GLOBAL_ACTIONS = 1 << 3;
 
     public static final int DISABLE2_NONE = 0x00000000;
 
     public static final int DISABLE2_MASK = DISABLE2_QUICK_SETTINGS | DISABLE2_SYSTEM_ICONS
-            | DISABLE2_NOTIFICATION_SHADE;
+            | DISABLE2_NOTIFICATION_SHADE | DISABLE2_GLOBAL_ACTIONS;
 
     @IntDef(flag = true,
             value = {DISABLE2_NONE, DISABLE2_MASK, DISABLE2_QUICK_SETTINGS, DISABLE2_SYSTEM_ICONS,
-                    DISABLE2_NOTIFICATION_SHADE})
+                    DISABLE2_NOTIFICATION_SHADE, DISABLE2_GLOBAL_ACTIONS})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Disable2Flags {}
 
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 402e209..895d12a 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -77,7 +77,7 @@
     }
 
     @Override
-    public void onTaskRemovalStarted(int taskId) {
+    public void onTaskRemovalStarted(int taskId) throws RemoteException {
     }
 
     @Override
@@ -91,11 +91,10 @@
     }
 
     @Override
-    public void onTaskProfileLocked(int taskId, int userId) {
+    public void onTaskProfileLocked(int taskId, int userId) throws RemoteException {
     }
 
     @Override
-    public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot)
-            throws RemoteException {
+    public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException {
     }
 }
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 6b40538..251863c 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -511,7 +511,8 @@
         return windowingMode != WINDOWING_MODE_FREEFORM && windowingMode != WINDOWING_MODE_PINNED;
     }
 
-    private static String windowingModeToString(@WindowingMode int windowingMode) {
+    /** @hide */
+    public static String windowingModeToString(@WindowingMode int windowingMode) {
         switch (windowingMode) {
             case WINDOWING_MODE_UNDEFINED: return "undefined";
             case WINDOWING_MODE_FULLSCREEN: return "fullscreen";
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index d9b7cd7..e491a4f 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -616,6 +616,9 @@
         CharSequence[] mAutofillOptions;
         boolean mSanitized;
         HtmlInfo mHtmlInfo;
+        int mMinEms = -1;
+        int mMaxEms = -1;
+        int mMaxLength = -1;
 
         // POJO used to override some autofill-related values when the node is parcelized.
         // Not written to parcel.
@@ -713,6 +716,9 @@
                 if (p instanceof HtmlInfo) {
                     mHtmlInfo = (HtmlInfo) p;
                 }
+                mMinEms = in.readInt();
+                mMaxEms = in.readInt();
+                mMaxLength = in.readInt();
             }
             if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
                 mX = in.readInt();
@@ -876,6 +882,9 @@
                 } else {
                     out.writeParcelable(null, 0);
                 }
+                out.writeInt(mMinEms);
+                out.writeInt(mMaxEms);
+                out.writeInt(mMaxLength);
             }
             if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
                 out.writeInt(mX);
@@ -1444,6 +1453,39 @@
         public ViewNode getChildAt(int index) {
             return mChildren[index];
         }
+
+        /**
+         * Returns the minimum width in ems of the text associated with this node, or {@code -1}
+         * if not supported by the node.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
+         * not for assist purposes.
+         */
+        public int getMinTextEms() {
+            return mMinEms;
+        }
+
+        /**
+         * Returns the maximum width in ems of the text associated with this node, or {@code -1}
+         * if not supported by the node.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
+         * not for assist purposes.
+         */
+        public int getMaxTextEms() {
+            return mMaxEms;
+        }
+
+        /**
+         * Returns the maximum length of the text associated with this node node, or {@code -1}
+         * if not supported by the node or not set.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
+         * not for assist purposes.
+         */
+        public int getMaxTextLength() {
+            return mMaxLength;
+        }
     }
 
     /**
@@ -1776,6 +1818,21 @@
         }
 
         @Override
+        public void setMinTextEms(int minEms) {
+            mNode.mMinEms = minEms;
+        }
+
+        @Override
+        public void setMaxTextEms(int maxEms) {
+            mNode.mMaxEms = maxEms;
+        }
+
+        @Override
+        public void setMaxTextLength(int maxLength) {
+            mNode.mMaxLength = maxLength;
+        }
+
+        @Override
         public void setDataIsSensitive(boolean sensitive) {
             mNode.mSanitized = !sensitive;
         }
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
index 3868439..0deb2e1 100644
--- a/core/java/android/app/job/JobScheduler.java
+++ b/core/java/android/app/job/JobScheduler.java
@@ -24,7 +24,6 @@
 import android.annotation.SystemService;
 import android.content.ClipData;
 import android.content.Context;
-import android.content.Intent;
 import android.os.Bundle;
 import android.os.PersistableBundle;
 
@@ -40,16 +39,18 @@
  * and how to construct them. You will construct these JobInfo objects and pass them to the
  * JobScheduler with {@link #schedule(JobInfo)}. When the criteria declared are met, the
  * system will execute this job on your application's {@link android.app.job.JobService}.
- * You identify which JobService is meant to execute the logic for your job when you create the
- * JobInfo with
+ * You identify the service component that implements the logic for your job when you
+ * construct the JobInfo using
  * {@link android.app.job.JobInfo.Builder#JobInfo.Builder(int,android.content.ComponentName)}.
  * </p>
  * <p>
- * The framework will be intelligent about when you receive your callbacks, and attempt to batch
- * and defer them as much as possible. Typically if you don't specify a deadline on your job, it
- * can be run at any moment depending on the current state of the JobScheduler's internal queue,
- * however it might be deferred as long as until the next time the device is connected to a power
- * source.
+ * The framework will be intelligent about when it executes jobs, and attempt to batch
+ * and defer them as much as possible. Typically if you don't specify a deadline on a job, it
+ * can be run at any moment depending on the current state of the JobScheduler's internal queue.
+ * <p>
+ * While a job is running, the system holds a wakelock on behalf of your app.  For this reason,
+ * you do not need to take any action to guarantee that the device stays awake for the
+ * duration of the job.
  * </p>
  * <p>You do not
  * instantiate this class directly; instead, retrieve it through
@@ -141,30 +142,34 @@
             int userId, String tag);
 
     /**
-     * Cancel a job that is pending in the JobScheduler.
-     * @param jobId unique identifier for this job. Obtain this value from the jobs returned by
-     * {@link #getAllPendingJobs()}.
+     * Cancel the specified job.  If the job is currently executing, it is stopped
+     * immediately and the return value from its {@link JobService#onStopJob(JobParameters)}
+     * method is ignored.
+     *
+     * @param jobId unique identifier for the job to be canceled, as supplied to
+     *     {@link JobInfo.Builder#JobInfo.Builder(int, android.content.ComponentName)
+     *     JobInfo.Builder(int, android.content.ComponentName)}.
      */
     public abstract void cancel(int jobId);
 
     /**
-     * Cancel all jobs that have been registered with the JobScheduler by this package.
+     * Cancel <em>all</em> jobs that have been scheduled by the calling application.
      */
     public abstract void cancelAll();
 
     /**
-     * Retrieve all jobs for this package that are pending in the JobScheduler.
+     * Retrieve all jobs that have been scheduled by the calling application.
      *
-     * @return a list of all the jobs registered by this package that have not
-     *         yet been executed.
+     * @return a list of all of the app's scheduled jobs.  This includes jobs that are
+     *     currently started as well as those that are still waiting to run.
      */
     public abstract @NonNull List<JobInfo> getAllPendingJobs();
 
     /**
-     * Retrieve a specific job for this package that is pending in the
-     * JobScheduler.
+     * Look up the description of a scheduled job.
      *
-     * @return job registered by this package that has not yet been executed.
+     * @return The {@link JobInfo} description of the given scheduled job, or {@code null}
+     *     if the supplied job ID does not correspond to any job.
      */
     public abstract @Nullable JobInfo getPendingJob(int jobId);
 }
diff --git a/core/java/android/app/job/JobService.java b/core/java/android/app/job/JobService.java
index 9096b47..69afed2 100644
--- a/core/java/android/app/job/JobService.java
+++ b/core/java/android/app/job/JobService.java
@@ -18,16 +18,7 @@
 
 import android.app.Service;
 import android.content.Intent;
-import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.lang.ref.WeakReference;
 
 /**
  * <p>Entry point for the callback from the {@link android.app.job.JobScheduler}.</p>
@@ -55,7 +46,7 @@
      * </pre>
      *
      * <p>If a job service is declared in the manifest but not protected with this
-     * permission, that service will be ignored by the OS.
+     * permission, that service will be ignored by the system.
      */
     public static final String PERMISSION_BIND =
             "android.permission.BIND_JOB_SERVICE";
@@ -81,14 +72,36 @@
     }
 
     /**
-     * Override this method with the callback logic for your job. Any such logic needs to be
-     * performed on a separate thread, as this function is executed on your application's main
-     * thread.
+     * Called to indicate that the job has begun executing.  Override this method with the
+     * logic for your job.  Like all other component lifecycle callbacks, this method executes
+     * on your application's main thread.
+     * <p>
+     * Return {@code true} from this method if your job needs to continue running.  If you
+     * do this, the job remains active until you call
+     * {@link #jobFinished(JobParameters, boolean)} to tell the system that it has completed
+     * its work, or until the job's required constraints are no longer satisfied.  For
+     * example, if the job was scheduled using
+     * {@link JobInfo.Builder#setRequiresCharging(boolean) setRequiresCharging(true)},
+     * it will be immediately halted by the system if the user unplugs the device from power,
+     * the job's {@link #onStopJob(JobParameters)} callback will be invoked, and the app
+     * will be expected to shut down all ongoing work connected with that job.
+     * <p>
+     * The system holds a wakelock on behalf of your app as long as your job is executing.
+     * This wakelock is acquired before this method is invoked, and is not released until either
+     * you call {@link #jobFinished(JobParameters, boolean)}, or after the system invokes
+     * {@link #onStopJob(JobParameters)} to notify your job that it is being shut down
+     * prematurely.
+     * <p>
+     * Returning {@code false} from this method means your job is already finished.  The
+     * system's wakelock for the job will be released, and {@link #onStopJob(JobParameters)}
+     * will not be invoked.
      *
-     * @param params Parameters specifying info about this job, including the extras bundle you
-     *               optionally provided at job-creation time.
-     * @return True if your service needs to process the work (on a separate thread). False if
-     * there's no more work to be done for this job.
+     * @param params Parameters specifying info about this job, including the optional
+     *     extras configured with {@link JobInfo.Builder#setExtras(android.os.PersistableBundle).
+     *     This object serves to identify this specific running job instance when calling
+     *     {@link #jobFinished(JobParameters, boolean)}.
+     * @return {@code true} if your service will continue running, using a separate thread
+     *     when appropriate.  {@code false} means that this job has completed its work.
      */
     public abstract boolean onStartJob(JobParameters params);
 
@@ -101,37 +114,44 @@
      * {@link android.app.job.JobInfo.Builder#setRequiredNetworkType(int)}, yet while your
      * job was executing the user toggled WiFi. Another example is if you had specified
      * {@link android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}, and the phone left its
-     * idle maintenance window. You are solely responsible for the behaviour of your application
-     * upon receipt of this message; your app will likely start to misbehave if you ignore it. One
-     * immediate repercussion is that the system will cease holding a wakelock for you.</p>
+     * idle maintenance window. You are solely responsible for the behavior of your application
+     * upon receipt of this message; your app will likely start to misbehave if you ignore it.
+     * <p>
+     * Once this method returns, the system releases the wakelock that it is holding on
+     * behalf of the job.</p>
      *
-     * @param params Parameters specifying info about this job.
-     * @return True to indicate to the JobManager whether you'd like to reschedule this job based
-     * on the retry criteria provided at job creation-time. False to drop the job. Regardless of
-     * the value returned, your job must stop executing.
+     * @param params The parameters identifying this job, as supplied to
+     *               the job in the {@link #onStartJob(JobParameters)} callback.
+     * @return {@code true} to indicate to the JobManager whether you'd like to reschedule
+     * this job based on the retry criteria provided at job creation-time; or {@code false}
+     * to end the job entirely.  Regardless of the value returned, your job must stop executing.
      */
     public abstract boolean onStopJob(JobParameters params);
 
     /**
-     * Call this to inform the JobManager you've finished executing. This can be called from any
-     * thread, as it will ultimately be run on your application's main thread. When the system
-     * receives this message it will release the wakelock being held.
+     * Call this to inform the JobScheduler that the job has finished its work.  When the
+     * system receives this message, it releases the wakelock being held for the job.
      * <p>
-     *     You can specify post-execution behaviour to the scheduler here with
-     *     <code>needsReschedule </code>. This will apply a back-off timer to your job based on
-     *     the default, or what was set with
-     *     {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}. The original
-     *     requirements are always honoured even for a backed-off job. Note that a job running in
-     *     idle mode will not be backed-off. Instead what will happen is the job will be re-added
-     *     to the queue and re-executed within a future idle maintenance window.
+     * You can request that the job be scheduled again by passing {@code true} as
+     * the <code>wantsReschedule</code> parameter. This will apply back-off policy
+     * for the job; this policy can be adjusted through the
+     * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)} method
+     * when the job is originally scheduled.  The job's initial
+     * requirements are preserved when jobs are rescheduled, regardless of backed-off
+     * policy.
+     * <p class="note">
+     * A job running while the device is dozing will not be rescheduled with the normal back-off
+     * policy.  Instead, the job will be re-added to the queue and executed again during
+     * a future idle maintenance window.
      * </p>
      *
-     * @param params Parameters specifying system-provided info about this job, this was given to
-     *               your application in {@link #onStartJob(JobParameters)}.
-     * @param needsReschedule True if this job should be rescheduled according to the back-off
-     *                        criteria specified at schedule-time. False otherwise.
+     * @param params The parameters identifying this job, as supplied to
+     *               the job in the {@link #onStartJob(JobParameters)} callback.
+     * @param wantsReschedule {@code true} if this job should be rescheduled according
+     *     to the back-off criteria specified when it was first scheduled; {@code false}
+     *     otherwise.
      */
-    public final void jobFinished(JobParameters params, boolean needsReschedule) {
-        mEngine.jobFinished(params, needsReschedule);
+    public final void jobFinished(JobParameters params, boolean wantsReschedule) {
+        mEngine.jobFinished(params, wantsReschedule);
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c9ad951..e47de75 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -53,6 +53,7 @@
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.XmlUtils;
 
@@ -9371,6 +9372,57 @@
         }
     }
 
+    /** @hide */
+    public void writeToProto(ProtoOutputStream proto, long fieldId, boolean secure, boolean comp,
+            boolean extras, boolean clip) {
+        long token = proto.start(fieldId);
+        if (mAction != null) {
+            proto.write(IntentProto.ACTION, mAction);
+        }
+        if (mCategories != null)  {
+            for (String category : mCategories) {
+                proto.write(IntentProto.CATEGORIES, category);
+            }
+        }
+        if (mData != null) {
+            proto.write(IntentProto.DATA, secure ? mData.toSafeString() : mData.toString());
+        }
+        if (mType != null) {
+            proto.write(IntentProto.TYPE, mType);
+        }
+        if (mFlags != 0) {
+            proto.write(IntentProto.FLAG, "0x" + Integer.toHexString(mFlags));
+        }
+        if (mPackage != null) {
+            proto.write(IntentProto.PACKAGE, mPackage);
+        }
+        if (comp && mComponent != null) {
+            proto.write(IntentProto.COMPONENT, mComponent.flattenToShortString());
+        }
+        if (mSourceBounds != null) {
+            proto.write(IntentProto.SOURCE_BOUNDS, mSourceBounds.toShortString());
+        }
+        if (mClipData != null) {
+            StringBuilder b = new StringBuilder();
+            if (clip) {
+                mClipData.toShortString(b);
+            } else {
+                mClipData.toShortStringShortItems(b, false);
+            }
+            proto.write(IntentProto.CLIP_DATA, b.toString());
+        }
+        if (extras && mExtras != null) {
+            proto.write(IntentProto.EXTRAS, mExtras.toShortString());
+        }
+        if (mContentUserHint != 0) {
+            proto.write(IntentProto.CONTENT_USER_HINT, mContentUserHint);
+        }
+        if (mSelector != null) {
+            proto.write(IntentProto.SELECTOR, mSelector.toShortString(secure, comp, extras, clip));
+        }
+        proto.end(token);
+    }
+
     /**
      * Call {@link #toUri} with 0 flags.
      * @deprecated Use {@link #toUri} instead.
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index c9bce53..a957aed 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -26,6 +26,7 @@
 import android.util.AndroidException;
 import android.util.Log;
 import android.util.Printer;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.XmlUtils;
 
@@ -918,6 +919,15 @@
             dest.writeInt(mPort);
         }
 
+        void writeToProto(ProtoOutputStream proto, long fieldId) {
+            long token = proto.start(fieldId);
+            // The original host information is already contained in host and wild, no output now.
+            proto.write(AuthorityEntryProto.HOST, mHost);
+            proto.write(AuthorityEntryProto.WILD, mWild);
+            proto.write(AuthorityEntryProto.PORT, mPort);
+            proto.end(token);
+        }
+
         public String getHost() {
             return mOrigHost;
         }
@@ -1739,6 +1749,59 @@
         }
     }
 
+    /** @hide */
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+        long token = proto.start(fieldId);
+        if (mActions.size() > 0) {
+            Iterator<String> it = mActions.iterator();
+            while (it.hasNext()) {
+                proto.write(IntentFilterProto.ACTIONS, it.next());
+            }
+        }
+        if (mCategories != null) {
+            Iterator<String> it = mCategories.iterator();
+            while (it.hasNext()) {
+                proto.write(IntentFilterProto.CATEGORIES, it.next());
+            }
+        }
+        if (mDataSchemes != null) {
+            Iterator<String> it = mDataSchemes.iterator();
+            while (it.hasNext()) {
+                proto.write(IntentFilterProto.DATA_SCHEMES, it.next());
+            }
+        }
+        if (mDataSchemeSpecificParts != null) {
+            Iterator<PatternMatcher> it = mDataSchemeSpecificParts.iterator();
+            while (it.hasNext()) {
+                it.next().writeToProto(proto, IntentFilterProto.DATA_SCHEME_SPECS);
+            }
+        }
+        if (mDataAuthorities != null) {
+            Iterator<AuthorityEntry> it = mDataAuthorities.iterator();
+            while (it.hasNext()) {
+                it.next().writeToProto(proto, IntentFilterProto.DATA_AUTHORITIES);
+            }
+        }
+        if (mDataPaths != null) {
+            Iterator<PatternMatcher> it = mDataPaths.iterator();
+            while (it.hasNext()) {
+                it.next().writeToProto(proto, IntentFilterProto.DATA_PATHS);
+            }
+        }
+        if (mDataTypes != null) {
+            Iterator<String> it = mDataTypes.iterator();
+            while (it.hasNext()) {
+                proto.write(IntentFilterProto.DATA_TYPES, it.next());
+            }
+        }
+        if (mPriority != 0 || mHasPartialTypes) {
+            proto.write(IntentFilterProto.PRIORITY, mPriority);
+            proto.write(IntentFilterProto.HAS_PARTIAL_TYPES, mHasPartialTypes);
+        }
+        proto.write(IntentFilterProto.GET_AUTO_VERIFY, getAutoVerify());
+        proto.end(token);
+    }
+
     public void dump(Printer du, String prefix) {
         StringBuilder sb = new StringBuilder(256);
         if (mActions.size() > 0) {
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index aa9562f..b94a410 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -20,8 +20,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
-import android.annotation.SystemService;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemService;
 import android.annotation.TestApi;
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetManager;
@@ -37,10 +37,10 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Rect;
+import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
-import android.graphics.drawable.AdaptiveIconDrawable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -282,12 +282,27 @@
         public static final int FLAG_GET_MANIFEST = FLAG_MATCH_MANIFEST;
 
         /**
-         * Does not retrieve CHOOSER only shortcuts.
-         * TODO: Add another flag for MATCH_ALL_PINNED
+         * @hide include all pinned shortcuts by any launchers, not just by the caller,
+         * in the result.
+         * If the caller doesn't havve the {@link android.Manifest.permission#ACCESS_SHORTCUTS}
+         * permission, this flag will be ignored.
+         */
+        @TestApi
+        public static final int FLAG_MATCH_ALL_PINNED = 1 << 10;
+
+        /**
+         * FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_MANIFEST
          * @hide
          */
         public static final int FLAG_MATCH_ALL_KINDS =
-                FLAG_GET_DYNAMIC | FLAG_GET_PINNED | FLAG_GET_MANIFEST;
+                FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_MANIFEST;
+
+        /**
+         * FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_MANIFEST | FLAG_MATCH_ALL_PINNED
+         * @hide
+         */
+        public static final int FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED =
+                FLAG_MATCH_ALL_KINDS | FLAG_MATCH_ALL_PINNED;
 
         /** @hide kept for unit tests */
         @Deprecated
@@ -319,6 +334,7 @@
                         FLAG_MATCH_PINNED,
                         FLAG_MATCH_MANIFEST,
                         FLAG_GET_KEY_FIELDS_ONLY,
+                        FLAG_MATCH_MANIFEST,
                 })
         @Retention(RetentionPolicy.SOURCE)
         public @interface QueryFlags {}
@@ -678,6 +694,21 @@
         }
     }
 
+    private List<ShortcutInfo> maybeUpdateDisabledMessage(List<ShortcutInfo> shortcuts) {
+        if (shortcuts == null) {
+            return null;
+        }
+        for (int i = shortcuts.size() - 1; i >= 0; i--) {
+            final ShortcutInfo si = shortcuts.get(i);
+            final String message = ShortcutInfo.getDisabledReasonForRestoreIssue(mContext,
+                    si.getDisabledReason());
+            if (message != null) {
+                si.setDisabledMessage(message);
+            }
+        }
+        return shortcuts;
+    }
+
     /**
      * Returns {@link ShortcutInfo}s that match {@code query}.
      *
@@ -698,10 +729,16 @@
             @NonNull UserHandle user) {
         logErrorForInvalidProfileAccess(user);
         try {
-            return mService.getShortcuts(mContext.getPackageName(),
+            // Note this is the only case we need to update the disabled message for shortcuts
+            // that weren't restored.
+            // The restore problem messages are only shown by the user, and publishers will never
+            // see them. The only other API that the launcher gets shortcuts is the shortcut
+            // changed callback, but that only returns shortcuts with the "key" information, so
+            // that won't return disabled message.
+            return maybeUpdateDisabledMessage(mService.getShortcuts(mContext.getPackageName(),
                     query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity,
                     query.mQueryFlags, user)
-                    .getList();
+                    .getList());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index be7f921..143c51d 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -467,6 +467,7 @@
     /** Updates the flags for the given permission. */
     public abstract void updatePermissionFlagsTEMP(@NonNull String permName,
             @NonNull String packageName, int flagMask, int flagValues, int userId);
-    /** temporary until mPermissionTrees is moved to PermissionManager */
-    public abstract Object enforcePermissionTreeTEMP(@NonNull String permName, int callingUid);
+    /** Returns a PermissionGroup. */
+    public abstract @Nullable PackageParser.PermissionGroup getPermissionGroupTEMP(
+            @NonNull String groupName);
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 6c7c8a07..ad36139a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3711,17 +3711,15 @@
                 ai.flags |= ApplicationInfo.FLAG_IS_GAME;
             }
 
-            if (false) {
-                if (sa.getBoolean(
-                        com.android.internal.R.styleable.AndroidManifestApplication_cantSaveState,
-                        false)) {
-                    ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
+            if (sa.getBoolean(
+                    com.android.internal.R.styleable.AndroidManifestApplication_cantSaveState,
+                    false)) {
+                ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
 
-                    // A heavy-weight application can not be in a custom process.
-                    // We can do direct compare because we intern all strings.
-                    if (ai.processName != null && ai.processName != ai.packageName) {
-                        outError[0] = "cantSaveState applications can not use custom processes";
-                    }
+                // A heavy-weight application can not be in a custom process.
+                // We can do direct compare because we intern all strings.
+                if (ai.processName != null && !ai.processName.equals(ai.packageName)) {
+                    outError[0] = "cantSaveState applications can not use custom processes";
                 }
             }
         }
@@ -6849,6 +6847,11 @@
             dest.writeParcelable(group, flags);
         }
 
+        /** @hide */
+        public boolean isAppOp() {
+            return info.isAppOp();
+        }
+
         private Permission(Parcel in) {
             super(in);
             final ClassLoader boot = Object.class.getClassLoader();
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index b45c26c..5dd7aed 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -353,6 +353,11 @@
         return size;
     }
 
+    /** @hide */
+    public boolean isAppOp() {
+        return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0;
+    }
+
     public static final Creator<PermissionInfo> CREATOR =
         new Creator<PermissionInfo>() {
         @Override
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 6b9c753..9ff0775 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -18,6 +18,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.annotation.UserIdInt;
 import android.app.TaskStackBuilder;
 import android.content.ComponentName;
@@ -100,6 +101,13 @@
     /** @hide When this is set, the bitmap icon is waiting to be saved. */
     public static final int FLAG_ICON_FILE_PENDING_SAVE = 1 << 11;
 
+    /**
+     * "Shadow" shortcuts are the ones that are restored, but the owner package hasn't been
+     * installed yet.
+     * @hide
+     */
+    public static final int FLAG_SHADOW = 1 << 12;
+
     /** @hide */
     @IntDef(flag = true,
             value = {
@@ -158,6 +166,124 @@
     public @interface CloneFlags {}
 
     /**
+     * Shortcut is not disabled.
+     */
+    public static final int DISABLED_REASON_NOT_DISABLED = 0;
+
+    /**
+     * Shortcut has been disabled by the publisher app with the
+     * {@link ShortcutManager#disableShortcuts(List)} API.
+     */
+    public static final int DISABLED_REASON_BY_APP = 1;
+
+    /**
+     * Shortcut has been disabled due to changes to the publisher app. (e.g. a manifest shortcut
+     * no longer exists.)
+     */
+    public static final int DISABLED_REASON_APP_CHANGED = 2;
+
+    /**
+     * A disabled reason that's equal to or bigger than this is due to backup and restore issue.
+     * A shortcut with such a reason wil be visible to the launcher, but not to the publisher.
+     * ({@link #isVisibleToPublisher()} will be false.)
+     */
+    private static final int DISABLED_REASON_RESTORE_ISSUE_START = 100;
+
+    /**
+     * Shortcut has been restored from the previous device, but the publisher app on the current
+     * device is of a lower version. The shortcut will not be usable until the app is upgraded to
+     * the same version or higher.
+     */
+    public static final int DISABLED_REASON_VERSION_LOWER = 100;
+
+    /**
+     * Shortcut has not been restored because the publisher app does not support backup and restore.
+     */
+    public static final int DISABLED_REASON_BACKUP_NOT_SUPPORTED = 101;
+
+    /**
+     * Shortcut has not been restored because the publisher app's signature has changed.
+     */
+    public static final int DISABLED_REASON_SIGNATURE_MISMATCH = 102;
+
+    /**
+     * Shortcut has not been restored for unknown reason.
+     */
+    public static final int DISABLED_REASON_OTHER_RESTORE_ISSUE = 103;
+
+    /** @hide */
+    @IntDef(value = {
+            DISABLED_REASON_NOT_DISABLED,
+            DISABLED_REASON_BY_APP,
+            DISABLED_REASON_APP_CHANGED,
+            DISABLED_REASON_VERSION_LOWER,
+            DISABLED_REASON_BACKUP_NOT_SUPPORTED,
+            DISABLED_REASON_SIGNATURE_MISMATCH,
+            DISABLED_REASON_OTHER_RESTORE_ISSUE,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DisabledReason{}
+
+    /**
+     * Return a label for disabled reasons, which are *not* supposed to be shown to the user.
+     * @hide
+     */
+    public static String getDisabledReasonDebugString(@DisabledReason int disabledReason) {
+        switch (disabledReason) {
+            case DISABLED_REASON_NOT_DISABLED:
+                return "[Not disabled]";
+            case DISABLED_REASON_BY_APP:
+                return "[Disabled: by app]";
+            case DISABLED_REASON_APP_CHANGED:
+                return "[Disabled: app changed]";
+            case DISABLED_REASON_VERSION_LOWER:
+                return "[Disabled: lower version]";
+            case DISABLED_REASON_BACKUP_NOT_SUPPORTED:
+                return "[Disabled: backup not supported]";
+            case DISABLED_REASON_SIGNATURE_MISMATCH:
+                return "[Disabled: signature mismatch]";
+            case DISABLED_REASON_OTHER_RESTORE_ISSUE:
+                return "[Disabled: unknown restore issue]";
+        }
+        return "[Disabled: unknown reason:" + disabledReason + "]";
+    }
+
+    /**
+     * Return a label for a disabled reason for shortcuts that are disabled due to a backup and
+     * restore issue. If the reason is not due to backup & restore, then it'll return null.
+     *
+     * This method returns localized, user-facing strings, which will be returned by
+     * {@link #getDisabledMessage()}.
+     *
+     * @hide
+     */
+    public static String getDisabledReasonForRestoreIssue(Context context,
+            @DisabledReason int disabledReason) {
+        final Resources res = context.getResources();
+
+        switch (disabledReason) {
+            case DISABLED_REASON_VERSION_LOWER:
+                return res.getString(
+                        com.android.internal.R.string.shortcut_restored_on_lower_version);
+            case DISABLED_REASON_BACKUP_NOT_SUPPORTED:
+                return res.getString(
+                        com.android.internal.R.string.shortcut_restore_not_supported);
+            case DISABLED_REASON_SIGNATURE_MISMATCH:
+                return res.getString(
+                        com.android.internal.R.string.shortcut_restore_signature_mismatch);
+            case DISABLED_REASON_OTHER_RESTORE_ISSUE:
+                return res.getString(
+                        com.android.internal.R.string.shortcut_restore_unknown_issue);
+        }
+        return null;
+    }
+
+    /** @hide */
+    public static boolean isDisabledForRestoreIssue(@DisabledReason int disabledReason) {
+        return disabledReason >= DISABLED_REASON_RESTORE_ISSUE_START;
+    }
+
+    /**
      * Shortcut category for messaging related actions, such as chat.
      */
     public static final String SHORTCUT_CATEGORY_CONVERSATION = "android.shortcut.conversation";
@@ -240,6 +366,11 @@
 
     private final int mUserId;
 
+    /** @hide */
+    public static final int VERSION_CODE_UNKNOWN = -1;
+
+    private int mDisabledReason;
+
     private ShortcutInfo(Builder b) {
         mUserId = b.mContext.getUserId();
 
@@ -352,6 +483,7 @@
         mActivity = source.mActivity;
         mFlags = source.mFlags;
         mLastChangedTimestamp = source.mLastChangedTimestamp;
+        mDisabledReason = source.mDisabledReason;
 
         // Just always keep it since it's cheep.
         mIconResId = source.mIconResId;
@@ -615,13 +747,23 @@
 
     /**
      * @hide
+     *
+     * @isUpdating set true if it's "update", as opposed to "replace".
      */
-    public void ensureUpdatableWith(ShortcutInfo source) {
+    public void ensureUpdatableWith(ShortcutInfo source, boolean isUpdating) {
+        if (isUpdating) {
+            Preconditions.checkState(isVisibleToPublisher(),
+                    "[Framework BUG] Invisible shortcuts can't be updated");
+        }
         Preconditions.checkState(mUserId == source.mUserId, "Owner User ID must match");
         Preconditions.checkState(mId.equals(source.mId), "ID must match");
         Preconditions.checkState(mPackageName.equals(source.mPackageName),
                 "Package name must match");
-        Preconditions.checkState(!isImmutable(), "Target ShortcutInfo is immutable");
+
+        if (isVisibleToPublisher()) {
+            // Don't do this check for restore-blocked shortcuts.
+            Preconditions.checkState(!isImmutable(), "Target ShortcutInfo is immutable");
+        }
     }
 
     /**
@@ -638,7 +780,7 @@
      * @hide
      */
     public void copyNonNullFieldsFrom(ShortcutInfo source) {
-        ensureUpdatableWith(source);
+        ensureUpdatableWith(source, /*isUpdating=*/ true);
 
         if (source.mActivity != null) {
             mActivity = source.mActivity;
@@ -1169,6 +1311,19 @@
         return mDisabledMessageResId;
     }
 
+    /** @hide */
+    public void setDisabledReason(@DisabledReason int reason) {
+        mDisabledReason = reason;
+    }
+
+    /**
+     * Returns why a shortcut has been disabled.
+     */
+    @DisabledReason
+    public int getDisabledReason() {
+        return mDisabledReason;
+    }
+
     /**
      * Return the shortcut's categories.
      *
@@ -1403,6 +1558,21 @@
         return hasFlags(FLAG_IMMUTABLE);
     }
 
+    /** @hide */
+    public boolean isDynamicVisible() {
+        return isDynamic() && isVisibleToPublisher();
+    }
+
+    /** @hide */
+    public boolean isPinnedVisible() {
+        return isPinned() && isVisibleToPublisher();
+    }
+
+    /** @hide */
+    public boolean isManifestVisible() {
+        return isDeclaredInManifest() && isVisibleToPublisher();
+    }
+
     /**
      * Return if a shortcut is immutable, in which case it cannot be modified with any of
      * {@link ShortcutManager} APIs.
@@ -1491,6 +1661,18 @@
     }
 
     /**
+     * When the system wasn't able to restore a shortcut, it'll still be registered to the system
+     * but disabled, and such shortcuts will not be visible to the publisher. They're still visible
+     * to launchers though.
+     *
+     * @hide
+     */
+    @TestApi
+    public boolean isVisibleToPublisher() {
+        return !isDisabledForRestoreIssue(mDisabledReason);
+    }
+
+    /**
      * Return whether a shortcut only contains "key" information only or not.  If true, only the
      * following fields are available.
      * <ul>
@@ -1668,6 +1850,7 @@
         mFlags = source.readInt();
         mIconResId = source.readInt();
         mLastChangedTimestamp = source.readLong();
+        mDisabledReason = source.readInt();
 
         if (source.readInt() == 0) {
             return; // key information only.
@@ -1711,6 +1894,7 @@
         dest.writeInt(mFlags);
         dest.writeInt(mIconResId);
         dest.writeLong(mLastChangedTimestamp);
+        dest.writeInt(mDisabledReason);
 
         if (hasKeyFieldsOnly()) {
             dest.writeInt(0);
@@ -1808,6 +1992,11 @@
         sb.append(", flags=0x");
         sb.append(Integer.toHexString(mFlags));
         sb.append(" [");
+        if ((mFlags & FLAG_SHADOW) != 0) {
+            // Note the shadow flag isn't actually used anywhere and it's just for dumpsys, so
+            // we don't have an isXxx for this.
+            sb.append("Sdw");
+        }
         if (!isEnabled()) {
             sb.append("Dis");
         }
@@ -1848,7 +2037,9 @@
         sb.append("packageName=");
         sb.append(mPackageName);
 
-        sb.append(", activity=");
+        addIndentOrComma(sb, indent);
+
+        sb.append("activity=");
         sb.append(mActivity);
 
         addIndentOrComma(sb, indent);
@@ -1883,6 +2074,11 @@
 
         addIndentOrComma(sb, indent);
 
+        sb.append("disabledReason=");
+        sb.append(getDisabledReasonDebugString(mDisabledReason));
+
+        addIndentOrComma(sb, indent);
+
         sb.append("categories=");
         sb.append(mCategories);
 
@@ -1953,7 +2149,7 @@
             CharSequence disabledMessage, int disabledMessageResId, String disabledMessageResName,
             Set<String> categories, Intent[] intentsWithExtras, int rank, PersistableBundle extras,
             long lastChangedTimestamp,
-            int flags, int iconResId, String iconResName, String bitmapPath) {
+            int flags, int iconResId, String iconResName, String bitmapPath, int disabledReason) {
         mUserId = userId;
         mId = id;
         mPackageName = packageName;
@@ -1978,5 +2174,6 @@
         mIconResId = iconResId;
         mIconResName = iconResName;
         mBitmapPath = bitmapPath;
+        mDisabledReason = disabledReason;
     }
 }
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index 7b7d8ae..7fc25d8 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -46,7 +46,7 @@
             @NonNull String callingPackage, long changedSince,
             @Nullable String packageName, @Nullable List<String> shortcutIds,
             @Nullable ComponentName componentName, @ShortcutQuery.QueryFlags int flags,
-            int userId);
+            int userId, int callingPid, int callingUid);
 
     public abstract boolean
             isPinnedByCaller(int launcherUserId, @NonNull String callingPackage,
@@ -58,7 +58,8 @@
 
     public abstract Intent[] createShortcutIntents(
             int launcherUserId, @NonNull String callingPackage,
-            @NonNull String packageName, @NonNull String shortcutId, int userId);
+            @NonNull String packageName, @NonNull String shortcutId, int userId,
+            int callingPid, int callingUid);
 
     public abstract void addListener(@NonNull ShortcutChangeListener listener);
 
@@ -70,7 +71,7 @@
             @NonNull String packageName, @NonNull String shortcutId, int userId);
 
     public abstract boolean hasShortcutHostPermission(int launcherUserId,
-            @NonNull String callingPackage);
+            @NonNull String callingPackage, int callingPid, int callingUid);
 
     public abstract boolean requestPinAppWidget(@NonNull String callingPackage,
             @NonNull AppWidgetProviderInfo appWidget, @Nullable Bundle extras,
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index a8b8c4b..386239c 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -796,7 +796,7 @@
                 dr = Drawable.createFromResourceStream(wrapper, value, is, file, null);
                 is.close();
             }
-        } catch (Exception e) {
+        } catch (Exception | StackOverflowError e) {
             Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
             final NotFoundException rnf = new NotFoundException(
                     "File " + file + " from drawable resource ID #0x" + Integer.toHexString(id));
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 2c9fb23..4e474c8 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -683,9 +683,9 @@
      */
     public boolean hasIPv4Address() {
         for (LinkAddress address : mLinkAddresses) {
-          if (address.getAddress() instanceof Inet4Address) {
-            return true;
-          }
+            if (address.getAddress() instanceof Inet4Address) {
+                return true;
+            }
         }
         return false;
     }
@@ -725,9 +725,9 @@
      */
     public boolean hasIPv4DefaultRoute() {
         for (RouteInfo r : mRoutes) {
-          if (r.isIPv4Default()) {
-            return true;
-          }
+            if (r.isIPv4Default()) {
+                return true;
+            }
         }
         return false;
     }
@@ -740,9 +740,9 @@
      */
     public boolean hasIPv6DefaultRoute() {
         for (RouteInfo r : mRoutes) {
-          if (r.isIPv6Default()) {
-            return true;
-          }
+            if (r.isIPv6Default()) {
+                return true;
+            }
         }
         return false;
     }
@@ -755,9 +755,9 @@
      */
     public boolean hasIPv4DnsServer() {
         for (InetAddress ia : mDnses) {
-          if (ia instanceof Inet4Address) {
-            return true;
-          }
+            if (ia instanceof Inet4Address) {
+                return true;
+            }
         }
         return false;
     }
@@ -770,9 +770,9 @@
      */
     public boolean hasIPv6DnsServer() {
         for (InetAddress ia : mDnses) {
-          if (ia instanceof Inet6Address) {
-            return true;
-          }
+            if (ia instanceof Inet6Address) {
+                return true;
+            }
         }
         return false;
     }
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 9881927..5995696 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1911,6 +1911,13 @@
             long elapsedRealtimeUs, int which);
 
     /**
+     * Returns the {@link Timer} object that tracks the given screen brightness.
+     *
+     * {@hide}
+     */
+    public abstract Timer getScreenBrightnessTimer(int brightnessBin);
+
+    /**
      * Returns the time in microseconds that power save mode has been enabled while the device was
      * running on battery.
      *
@@ -2019,6 +2026,14 @@
             long elapsedRealtimeUs, int which);
 
     /**
+     * Returns the {@link Timer} object that tracks how much the phone has been trying to
+     * acquire a signal.
+     *
+     * {@hide}
+     */
+    public abstract Timer getPhoneSignalScanningTimer();
+
+    /**
      * Returns the number of times the phone has entered the given signal strength.
      *
      * {@hide}
@@ -2026,6 +2041,12 @@
     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
 
     /**
+     * Return the {@link Timer} object used to track the given signal strength's duration and
+     * counts.
+     */
+    protected abstract Timer getPhoneSignalStrengthTimer(int strengthBin);
+
+    /**
      * Returns the time in microseconds that the mobile network has been active
      * (in a high power state).
      *
@@ -2108,6 +2129,11 @@
      */
     public abstract int getPhoneDataConnectionCount(int dataType, int which);
 
+    /**
+     * Returns the {@link Timer} object that tracks the phone's data connection type stats.
+     */
+    public abstract Timer getPhoneDataConnectionTimer(int dataType);
+
     public static final int WIFI_SUPPL_STATE_INVALID = 0;
     public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
     public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
@@ -2267,6 +2293,13 @@
     public abstract int getWifiStateCount(int wifiState, int which);
 
     /**
+     * Returns the {@link Timer} object that tracks the given WiFi state.
+     *
+     * {@hide}
+     */
+    public abstract Timer getWifiStateTimer(int wifiState);
+
+    /**
      * Returns the time in microseconds that the wifi supplicant has been
      * in a given state.
      *
@@ -2282,6 +2315,13 @@
      */
     public abstract int getWifiSupplStateCount(int state, int which);
 
+    /**
+     * Returns the {@link Timer} object that tracks the given wifi supplicant state.
+     *
+     * {@hide}
+     */
+    public abstract Timer getWifiSupplStateTimer(int state);
+
     public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
 
     /**
@@ -2301,6 +2341,13 @@
     public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
 
     /**
+     * Returns the {@link Timer} object that tracks the given WIFI signal strength.
+     *
+     * {@hide}
+     */
+    public abstract Timer getWifiSignalStrengthTimer(int strengthBin);
+
+    /**
      * Returns the time in microseconds that the flashlight has been on while the device was
      * running on battery.
      *
@@ -2487,13 +2534,13 @@
     public abstract int getDischargeAmountScreenOffSinceCharge();
 
     /**
-     * Get the amount the battery has discharged while the screen was doze,
+     * Get the amount the battery has discharged while the screen was dozing,
      * since the last time power was unplugged.
      */
     public abstract int getDischargeAmountScreenDoze();
 
     /**
-     * Get the amount the battery has discharged while the screen was doze,
+     * Get the amount the battery has discharged while the screen was dozing,
      * since the last time the device was charged.
      */
     public abstract int getDischargeAmountScreenDozeSinceCharge();
@@ -2626,20 +2673,20 @@
      * micro-Ampere-hours. This will be non-zero only if the device's battery has
      * a coulomb counter.
      */
-    public abstract long getMahDischargeScreenOff(int which);
+    public abstract long getUahDischargeScreenOff(int which);
 
     /**
      * Return the amount of battery discharge while the screen was in doze mode, measured in
      * micro-Ampere-hours. This will be non-zero only if the device's battery has
      * a coulomb counter.
      */
-    public abstract long getMahDischargeScreenDoze(int which);
+    public abstract long getUahDischargeScreenDoze(int which);
 
     /**
      * Return the amount of battery discharge  measured in micro-Ampere-hours. This will be
      * non-zero only if the device's battery has a coulomb counter.
      */
-    public abstract long getMahDischarge(int which);
+    public abstract long getUahDischarge(int which);
 
     /**
      * Returns the estimated real battery capacity, which may be less than the capacity
@@ -2984,7 +3031,7 @@
             final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
                     / 1000;
             final int count = timer.getCountLocked(which);
-            if (totalTime != 0) {
+            if (totalTime != 0 || count != 0) {
                 dumpLine(pw, uid, category, type, totalTime, count);
             }
         }
@@ -3000,12 +3047,12 @@
      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
      */
     private static void dumpTimer(ProtoOutputStream proto, long fieldId,
-                                        Timer timer, long rawRealtime, int which) {
+                                        Timer timer, long rawRealtimeUs, int which) {
         if (timer == null) {
             return;
         }
         // Convert from microseconds to milliseconds with rounding
-        final long totalTimeMs = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+        final long totalTimeMs = (timer.getTotalTimeLocked(rawRealtimeUs, which) + 500) / 1000;
         final int count = timer.getCountLocked(which);
         if (totalTimeMs != 0 || count != 0) {
             final long token = proto.start(fieldId);
@@ -3114,71 +3161,104 @@
         final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
         final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
         final long powerDrainMaMs = counter.getPowerCounter().getCountLocked(which);
+        // Battery real time
+        final long totalControllerActivityTimeMs
+            = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
         long totalTxTimeMs = 0;
         for (LongCounter txState : counter.getTxTimeCounters()) {
             totalTxTimeMs += txState.getCountLocked(which);
         }
-
-        final long totalTimeMs = idleTimeMs + rxTimeMs + totalTxTimeMs;
+        final long sleepTimeMs
+            = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + totalTxTimeMs);
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  ");
+        sb.append("     ");
+        sb.append(controllerName);
+        sb.append(" Sleep time:  ");
+        formatTimeMs(sb, sleepTimeMs);
+        sb.append("(");
+        sb.append(formatRatioLocked(sleepTimeMs, totalControllerActivityTimeMs));
+        sb.append(")");
+        pw.println(sb.toString());
+
+        sb.setLength(0);
+        sb.append(prefix);
+        sb.append("     ");
         sb.append(controllerName);
         sb.append(" Idle time:   ");
         formatTimeMs(sb, idleTimeMs);
         sb.append("(");
-        sb.append(formatRatioLocked(idleTimeMs, totalTimeMs));
+        sb.append(formatRatioLocked(idleTimeMs, totalControllerActivityTimeMs));
         sb.append(")");
         pw.println(sb.toString());
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  ");
+        sb.append("     ");
         sb.append(controllerName);
         sb.append(" Rx time:     ");
         formatTimeMs(sb, rxTimeMs);
         sb.append("(");
-        sb.append(formatRatioLocked(rxTimeMs, totalTimeMs));
+        sb.append(formatRatioLocked(rxTimeMs, totalControllerActivityTimeMs));
         sb.append(")");
         pw.println(sb.toString());
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  ");
+        sb.append("     ");
         sb.append(controllerName);
         sb.append(" Tx time:     ");
-        formatTimeMs(sb, totalTxTimeMs);
-        sb.append("(");
-        sb.append(formatRatioLocked(totalTxTimeMs, totalTimeMs));
-        sb.append(")");
-        pw.println(sb.toString());
 
-        final int numTxLvls = counter.getTxTimeCounters().length;
+        String [] powerLevel;
+        switch(controllerName) {
+            case "Cellular":
+                powerLevel = new String[] {
+                    "   less than 0dBm: ",
+                    "   0dBm to 8dBm: ",
+                    "   8dBm to 15dBm: ",
+                    "   15dBm to 20dBm: ",
+                    "   above 20dBm: "};
+                break;
+            default:
+                powerLevel = new String[] {"[0]", "[1]", "[2]", "[3]", "[4]"};
+                break;
+        }
+        final int numTxLvls = Math.min(counter.getTxTimeCounters().length, powerLevel.length);
         if (numTxLvls > 1) {
+            pw.println(sb.toString());
             for (int lvl = 0; lvl < numTxLvls; lvl++) {
                 final long txLvlTimeMs = counter.getTxTimeCounters()[lvl].getCountLocked(which);
                 sb.setLength(0);
                 sb.append(prefix);
-                sb.append("    [");
-                sb.append(lvl);
-                sb.append("] ");
+                sb.append("    ");
+                sb.append(powerLevel[lvl]);
+                sb.append(" ");
                 formatTimeMs(sb, txLvlTimeMs);
                 sb.append("(");
-                sb.append(formatRatioLocked(txLvlTimeMs, totalTxTimeMs));
+                sb.append(formatRatioLocked(txLvlTimeMs, totalControllerActivityTimeMs));
                 sb.append(")");
                 pw.println(sb.toString());
             }
+        } else {
+            final long txLvlTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which);
+            formatTimeMs(sb, txLvlTimeMs);
+            sb.append("(");
+            sb.append(formatRatioLocked(txLvlTimeMs, totalControllerActivityTimeMs));
+            sb.append(")");
+            pw.println(sb.toString());
         }
 
-        sb.setLength(0);
-        sb.append(prefix);
-        sb.append("  ");
-        sb.append(controllerName);
-        sb.append(" Power drain: ").append(
+        if (powerDrainMaMs > 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+            sb.append("     ");
+            sb.append(controllerName);
+            sb.append(" Battery drain: ").append(
                 BatteryStatsHelper.makemAh(powerDrainMaMs / (double) (1000*60*60)));
-        sb.append("mAh");
-        pw.println(sb.toString());
+            sb.append("mAh");
+            pw.println(sb.toString());
+        }
     }
 
     /**
@@ -3191,13 +3271,13 @@
     /**
      * Checkin server version of dump to produce more compact, computer-readable log.
      *
-     * NOTE: all times are expressed in 'ms'.
+     * NOTE: all times are expressed in microseconds, unless specified otherwise.
      */
     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
             boolean wifiOnly) {
         final long rawUptime = SystemClock.uptimeMillis() * 1000;
-        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
-        final long rawRealtimeMs = (rawRealtime + 500) / 1000;
+        final long rawRealtimeMs = SystemClock.elapsedRealtime();
+        final long rawRealtime = rawRealtimeMs * 1000;
         final long batteryUptime = getBatteryUptime(rawUptime);
         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
@@ -3220,9 +3300,9 @@
                 rawRealtime, which);
         final int connChanges = getNumConnectivityChange(which);
         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
-        final long dischargeCount = getMahDischarge(which);
-        final long dischargeScreenOffCount = getMahDischargeScreenOff(which);
-        final long dischargeScreenDozeCount = getMahDischargeScreenDoze(which);
+        final long dischargeCount = getUahDischarge(which);
+        final long dischargeScreenOffCount = getUahDischargeScreenOff(which);
+        final long dischargeScreenDozeCount = getUahDischargeScreenDoze(which);
 
         final StringBuilder sb = new StringBuilder(128);
 
@@ -3460,9 +3540,9 @@
                     BatteryStatsHelper.makemAh(helper.getComputedPower()),
                     BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
                     BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
+            int uid = 0;
             for (int i=0; i<sippers.size(); i++) {
                 final BatterySipper bs = sippers.get(i);
-                int uid = 0;
                 String label;
                 switch (bs.drainType) {
                     case IDLE:
@@ -3503,6 +3583,9 @@
                     case CAMERA:
                         label = "camera";
                         break;
+                    case MEMORY:
+                        label = "memory";
+                        break;
                     default:
                         label = "???";
                 }
@@ -3523,6 +3606,7 @@
             dumpLine(pw, 0 /* uid */, category, GLOBAL_CPU_FREQ_DATA, sb.toString());
         }
 
+        // Dump stats per UID.
         for (int iu = 0; iu < NU; iu++) {
             final int uid = uidStats.keyAt(iu);
             if (reqUid >= 0 && uid != reqUid) {
@@ -4020,7 +4104,7 @@
             pw.println(sb.toString());
         }
 
-        final long dischargeCount = getMahDischarge(which);
+        final long dischargeCount = getUahDischarge(which);
         if (dischargeCount >= 0) {
             sb.setLength(0);
             sb.append(prefix);
@@ -4030,7 +4114,7 @@
             pw.println(sb.toString());
         }
 
-        final long dischargeScreenOffCount = getMahDischargeScreenOff(which);
+        final long dischargeScreenOffCount = getUahDischargeScreenOff(which);
         if (dischargeScreenOffCount >= 0) {
             sb.setLength(0);
             sb.append(prefix);
@@ -4040,7 +4124,7 @@
             pw.println(sb.toString());
         }
 
-        final long dischargeScreenDozeCount = getMahDischargeScreenDoze(which);
+        final long dischargeScreenDozeCount = getUahDischargeScreenDoze(which);
         if (dischargeScreenDozeCount >= 0) {
             sb.setLength(0);
             sb.append(prefix);
@@ -4246,51 +4330,50 @@
             pw.println(sb.toString());
         }
 
+        pw.println("");
         pw.print(prefix);
-                pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
-                pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
-                pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
-                pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Phone signal levels:");
-        didOne = false;
-        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
-            final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
-            if (time == 0) {
-                continue;
-            }
-            sb.append("\n    ");
-            sb.append(prefix);
-            didOne = true;
-            sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
-            sb.append(" ");
-            formatTimeMs(sb, time/1000);
-            sb.append("(");
-            sb.append(formatRatioLocked(time, whichBatteryRealtime));
-            sb.append(") ");
-            sb.append(getPhoneSignalStrengthCount(i, which));
-            sb.append("x");
-        }
-        if (!didOne) sb.append(" (no activity)");
+        sb.append("  CONNECTIVITY POWER SUMMARY START");
+        pw.println(sb.toString());
+
+        pw.print(prefix);
+        sb.setLength(0);
+        sb.append(prefix);
+        sb.append("  Logging duration for connectivity statistics: ");
+        formatTimeMs(sb, whichBatteryRealtime / 1000);
         pw.println(sb.toString());
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Signal scanning time: ");
-        formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
+        sb.append("  Cellular Statistics:");
         pw.println(sb.toString());
 
+        pw.print(prefix);
+        sb.setLength(0);
+        sb.append(prefix);
+        sb.append("     Cellular kernel active time: ");
+        final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
+        formatTimeMs(sb, mobileActiveTime / 1000);
+        sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
+        sb.append(")");
+        pw.println(sb.toString());
+
+        pw.print("     Cellular data received: "); pw.println(formatBytesLocked(mobileRxTotalBytes));
+        pw.print("     Cellular data sent: "); pw.println(formatBytesLocked(mobileTxTotalBytes));
+        pw.print("     Cellular packets received: "); pw.println(mobileRxTotalPackets);
+        pw.print("     Cellular packets sent: "); pw.println(mobileTxTotalPackets);
+
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Radio types:");
+        sb.append("     Cellular Radio Access Technology:");
         didOne = false;
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
             final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
             if (time == 0) {
                 continue;
             }
-            sb.append("\n    ");
+            sb.append("\n       ");
             sb.append(prefix);
             didOne = true;
             sb.append(DATA_CONNECTION_NAMES[i]);
@@ -4299,73 +4382,64 @@
             sb.append("(");
             sb.append(formatRatioLocked(time, whichBatteryRealtime));
             sb.append(") ");
-            sb.append(getPhoneDataConnectionCount(i, which));
-            sb.append("x");
         }
         if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Mobile radio active time: ");
-        final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
-        formatTimeMs(sb, mobileActiveTime / 1000);
-        sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
-        sb.append(") "); sb.append(getMobileRadioActiveCount(which));
-        sb.append("x");
+        sb.append("     Cellular Rx signal strength (RSRP):");
+        final String[] cellularRxSignalStrengthDescription = new String[]{
+            "very poor (less than -128dBm): ",
+            "poor (-128dBm to -118dBm): ",
+            "moderate (-118dBm to -108dBm): ",
+            "good (-108dBm to -98dBm): ",
+            "great (greater than -98dBm): "};
+        didOne = false;
+        final int numCellularRxBins = Math.min(SignalStrength.NUM_SIGNAL_STRENGTH_BINS,
+            cellularRxSignalStrengthDescription.length);
+        for (int i=0; i<numCellularRxBins; i++) {
+            final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
+            if (time == 0) {
+                continue;
+            }
+            sb.append("\n       ");
+            sb.append(prefix);
+            didOne = true;
+            sb.append(cellularRxSignalStrengthDescription[i]);
+            sb.append(" ");
+            formatTimeMs(sb, time/1000);
+            sb.append("(");
+            sb.append(formatRatioLocked(time, whichBatteryRealtime));
+            sb.append(") ");
+        }
+        if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
 
-        final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
-        if (mobileActiveUnknownTime != 0) {
-            sb.setLength(0);
-            sb.append(prefix);
-            sb.append("  Mobile radio active unknown time: ");
-            formatTimeMs(sb, mobileActiveUnknownTime / 1000);
-            sb.append("(");
-            sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
-            sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
-            sb.append("x");
-            pw.println(sb.toString());
-        }
-
-        final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
-        if (mobileActiveAdjustedTime != 0) {
-            sb.setLength(0);
-            sb.append(prefix);
-            sb.append("  Mobile radio active adjusted time: ");
-            formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
-            sb.append("(");
-            sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
-            sb.append(")");
-            pw.println(sb.toString());
-        }
-
-        printControllerActivity(pw, sb, prefix, "Radio", getModemControllerActivity(), which);
+        printControllerActivity(pw, sb, prefix, "Cellular",
+            getModemControllerActivity(), which);
 
         pw.print(prefix);
-                pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
-                pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
-                pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
-                pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
         sb.setLength(0);
         sb.append(prefix);
-                sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
-                sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
-                sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
-                sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
-                sb.append(")");
+        sb.append("  Wifi Statistics:");
         pw.println(sb.toString());
 
+        pw.print("     Wifi data received: "); pw.println(formatBytesLocked(wifiRxTotalBytes));
+        pw.print("     Wifi data sent: "); pw.println(formatBytesLocked(wifiTxTotalBytes));
+        pw.print("     Wifi packets received: "); pw.println(wifiRxTotalPackets);
+        pw.print("     Wifi packets sent: "); pw.println(wifiTxTotalPackets);
+
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Wifi states:");
+        sb.append("     Wifi states:");
         didOne = false;
         for (int i=0; i<NUM_WIFI_STATES; i++) {
             final long time = getWifiStateTime(i, rawRealtime, which);
             if (time == 0) {
                 continue;
             }
-            sb.append("\n    ");
+            sb.append("\n       ");
             didOne = true;
             sb.append(WIFI_STATE_NAMES[i]);
             sb.append(" ");
@@ -4373,22 +4447,20 @@
             sb.append("(");
             sb.append(formatRatioLocked(time, whichBatteryRealtime));
             sb.append(") ");
-            sb.append(getWifiStateCount(i, which));
-            sb.append("x");
         }
         if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Wifi supplicant states:");
+        sb.append("     Wifi supplicant states:");
         didOne = false;
         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
             final long time = getWifiSupplStateTime(i, rawRealtime, which);
             if (time == 0) {
                 continue;
             }
-            sb.append("\n    ");
+            sb.append("\n       ");
             didOne = true;
             sb.append(WIFI_SUPPL_STATE_NAMES[i]);
             sb.append(" ");
@@ -4396,17 +4468,23 @@
             sb.append("(");
             sb.append(formatRatioLocked(time, whichBatteryRealtime));
             sb.append(") ");
-            sb.append(getWifiSupplStateCount(i, which));
-            sb.append("x");
         }
         if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Wifi signal levels:");
+        sb.append("     Wifi Rx signal strength (RSSI):");
+        final String[] wifiRxSignalStrengthDescription = new String[]{
+            "very poor (less than -88.75dBm): ",
+            "poor (-88.75 to -77.5dBm): ",
+            "moderate (-77.5dBm to -66.25dBm): ",
+            "good (-66.25dBm to -55dBm): ",
+            "great (greater than -55dBm): "};
         didOne = false;
-        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
+        final int numWifiRxBins = Math.min(NUM_WIFI_SIGNAL_STRENGTH_BINS,
+            wifiRxSignalStrengthDescription.length);
+        for (int i=0; i<numWifiRxBins; i++) {
             final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
             if (time == 0) {
                 continue;
@@ -4414,15 +4492,12 @@
             sb.append("\n    ");
             sb.append(prefix);
             didOne = true;
-            sb.append("level(");
-            sb.append(i);
-            sb.append(") ");
+            sb.append("     ");
+            sb.append(wifiRxSignalStrengthDescription[i]);
             formatTimeMs(sb, time/1000);
             sb.append("(");
             sb.append(formatRatioLocked(time, whichBatteryRealtime));
             sb.append(") ");
-            sb.append(getWifiSignalStrengthCount(i, which));
-            sb.append("x");
         }
         if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
@@ -4430,6 +4505,13 @@
         printControllerActivity(pw, sb, prefix, "WiFi", getWifiControllerActivity(), which);
 
         pw.print(prefix);
+        sb.setLength(0);
+        sb.append(prefix);
+        sb.append("  CONNECTIVITY POWER SUMMARY END");
+        pw.println(sb.toString());
+        pw.println("");
+
+        pw.print(prefix);
         pw.print("  Bluetooth total received: "); pw.print(formatBytesLocked(btRxTotalBytes));
         pw.print(", sent: "); pw.println(formatBytesLocked(btTxTotalBytes));
 
@@ -6038,6 +6120,61 @@
         return true;
     }
 
+    private static void dumpDurationSteps(ProtoOutputStream proto, long fieldId,
+            LevelStepTracker steps) {
+        if (steps == null) {
+            return;
+        }
+        int count = steps.mNumStepDurations;
+        long token;
+        for (int i = 0; i < count; ++i) {
+            token = proto.start(fieldId);
+            proto.write(SystemProto.BatteryLevelStep.DURATION_MS, steps.getDurationAt(i));
+            proto.write(SystemProto.BatteryLevelStep.LEVEL, steps.getLevelAt(i));
+
+            final long initMode = steps.getInitModeAt(i);
+            final long modMode = steps.getModModeAt(i);
+
+            int ds = SystemProto.BatteryLevelStep.DS_MIXED;
+            if ((modMode & STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
+                switch ((int) (initMode & STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
+                    case Display.STATE_OFF:
+                        ds = SystemProto.BatteryLevelStep.DS_OFF;
+                        break;
+                    case Display.STATE_ON:
+                        ds = SystemProto.BatteryLevelStep.DS_ON;
+                        break;
+                    case Display.STATE_DOZE:
+                        ds = SystemProto.BatteryLevelStep.DS_DOZE;
+                        break;
+                    case Display.STATE_DOZE_SUSPEND:
+                        ds = SystemProto.BatteryLevelStep.DS_DOZE_SUSPEND;
+                        break;
+                    default:
+                        ds = SystemProto.BatteryLevelStep.DS_ERROR;
+                        break;
+                }
+            }
+            proto.write(SystemProto.BatteryLevelStep.DISPLAY_STATE, ds);
+
+            int psm = SystemProto.BatteryLevelStep.PSM_MIXED;
+            if ((modMode & STEP_LEVEL_MODE_POWER_SAVE) == 0) {
+                psm = (initMode & STEP_LEVEL_MODE_POWER_SAVE) != 0
+                    ? SystemProto.BatteryLevelStep.PSM_ON : SystemProto.BatteryLevelStep.PSM_OFF;
+            }
+            proto.write(SystemProto.BatteryLevelStep.POWER_SAVE_MODE, psm);
+
+            int im = SystemProto.BatteryLevelStep.IM_MIXED;
+            if ((modMode & STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
+                im = (initMode & STEP_LEVEL_MODE_DEVICE_IDLE) != 0
+                    ? SystemProto.BatteryLevelStep.IM_ON : SystemProto.BatteryLevelStep.IM_OFF;
+            }
+            proto.write(SystemProto.BatteryLevelStep.IDLE_MODE, im);
+
+            proto.end(token);
+        }
+    }
+
     public static final int DUMP_CHARGED_ONLY = 1<<1;
     public static final int DUMP_DAILY_ONLY = 1<<2;
     public static final int DUMP_HISTORY_ONLY = 1<<3;
@@ -6463,7 +6600,7 @@
         }
     }
 
-    /** Dump batterystats data to a proto. @hide */
+    /** Dump #STATS_SINCE_CHARGED batterystats data to a proto. @hide */
     public void dumpProtoLocked(Context context, FileDescriptor fd, List<ApplicationInfo> apps,
             int flags, long historyStart) {
         final ProtoOutputStream proto = new ProtoOutputStream(fd);
@@ -6485,10 +6622,376 @@
 
         if ((flags & (DUMP_HISTORY_ONLY | DUMP_DAILY_ONLY)) == 0) {
             // TODO: implement dumpProtoAppsLocked(proto, apps);
-            // TODO: implement dumpProtoSystemLocked(proto);
+            dumpProtoSystemLocked(context, proto, (flags & DUMP_DEVICE_WIFI_ONLY) != 0);
         }
 
         proto.end(bToken);
         proto.flush();
     }
+
+    private void dumpProtoSystemLocked(Context context, ProtoOutputStream proto, boolean wifiOnly) {
+        final long sToken = proto.start(BatteryStatsProto.SYSTEM);
+        final long rawUptimeUs = SystemClock.uptimeMillis() * 1000;
+        final long rawRealtimeMs = SystemClock.elapsedRealtime();
+        final long rawRealtimeUs = rawRealtimeMs * 1000;
+        final int which = STATS_SINCE_CHARGED;
+
+        // Battery data (BATTERY_DATA)
+        long token = proto.start(SystemProto.BATTERY);
+        proto.write(SystemProto.Battery.START_CLOCK_TIME_MS, getStartClockTime());
+        proto.write(SystemProto.Battery.START_COUNT, getStartCount());
+        proto.write(SystemProto.Battery.TOTAL_REALTIME_MS,
+                computeRealtime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Battery.TOTAL_UPTIME_MS,
+                computeUptime(rawUptimeUs, which) / 1000);
+        proto.write(SystemProto.Battery.BATTERY_REALTIME_MS,
+                computeBatteryRealtime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Battery.BATTERY_UPTIME_MS,
+                computeBatteryUptime(rawUptimeUs, which) / 1000);
+        proto.write(SystemProto.Battery.SCREEN_OFF_REALTIME_MS,
+                computeBatteryScreenOffRealtime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Battery.SCREEN_OFF_UPTIME_MS,
+                computeBatteryScreenOffUptime(rawUptimeUs, which) / 1000);
+        proto.write(SystemProto.Battery.SCREEN_DOZE_DURATION_MS,
+                getScreenDozeTime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Battery.ESTIMATED_BATTERY_CAPACITY_MAH,
+                getEstimatedBatteryCapacity());
+        proto.write(SystemProto.Battery.MIN_LEARNED_BATTERY_CAPACITY_UAH,
+                getMinLearnedBatteryCapacity());
+        proto.write(SystemProto.Battery.MAX_LEARNED_BATTERY_CAPACITY_UAH,
+                getMaxLearnedBatteryCapacity());
+        proto.end(token);
+
+        // Battery discharge (BATTERY_DISCHARGE_DATA)
+        token = proto.start(SystemProto.BATTERY_DISCHARGE);
+        proto.write(SystemProto.BatteryDischarge.LOWER_BOUND_SINCE_CHARGE,
+                getLowDischargeAmountSinceCharge());
+        proto.write(SystemProto.BatteryDischarge.UPPER_BOUND_SINCE_CHARGE,
+                getHighDischargeAmountSinceCharge());
+        proto.write(SystemProto.BatteryDischarge.SCREEN_ON_SINCE_CHARGE,
+                getDischargeAmountScreenOnSinceCharge());
+        proto.write(SystemProto.BatteryDischarge.SCREEN_OFF_SINCE_CHARGE,
+                getDischargeAmountScreenOffSinceCharge());
+        proto.write(SystemProto.BatteryDischarge.SCREEN_DOZE_SINCE_CHARGE,
+                getDischargeAmountScreenDozeSinceCharge());
+        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH,
+                getUahDischarge(which) / 1000);
+        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_SCREEN_OFF,
+                getUahDischargeScreenOff(which) / 1000);
+        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_SCREEN_DOZE,
+                getUahDischargeScreenDoze(which) / 1000);
+        proto.end(token);
+
+        // Time remaining
+        long timeRemainingUs = computeChargeTimeRemaining(rawRealtimeUs);
+        if (timeRemainingUs >= 0) {
+            // Charge time remaining (CHARGE_TIME_REMAIN_DATA)
+            proto.write(SystemProto.CHARGE_TIME_REMAINING_MS, timeRemainingUs / 1000);
+        } else {
+            timeRemainingUs = computeBatteryTimeRemaining(rawRealtimeUs);
+            // Discharge time remaining (DISCHARGE_TIME_REMAIN_DATA)
+            if (timeRemainingUs >= 0) {
+                proto.write(SystemProto.DISCHARGE_TIME_REMAINING_MS, timeRemainingUs / 1000);
+            } else {
+                proto.write(SystemProto.DISCHARGE_TIME_REMAINING_MS, -1);
+            }
+        }
+
+        // Charge step (CHARGE_STEP_DATA)
+        dumpDurationSteps(proto, SystemProto.CHARGE_STEP, getChargeLevelStepTracker());
+
+        // Phone data connection (DATA_CONNECTION_TIME_DATA and DATA_CONNECTION_COUNT_DATA)
+        for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; ++i) {
+            token = proto.start(SystemProto.DATA_CONNECTION);
+            proto.write(SystemProto.DataConnection.NAME, i);
+            dumpTimer(proto, SystemProto.DataConnection.TOTAL, getPhoneDataConnectionTimer(i),
+                    rawRealtimeUs, which);
+            proto.end(token);
+        }
+
+        // Discharge step (DISCHARGE_STEP_DATA)
+        dumpDurationSteps(proto, SystemProto.DISCHARGE_STEP, getDischargeLevelStepTracker());
+
+        // CPU frequencies (GLOBAL_CPU_FREQ_DATA)
+        final long[] cpuFreqs = getCpuFreqs();
+        if (cpuFreqs != null) {
+            for (long i : cpuFreqs) {
+                proto.write(SystemProto.CPU_FREQUENCY, i);
+            }
+        }
+
+        // Bluetooth controller (GLOBAL_BLUETOOTH_CONTROLLER_DATA)
+        dumpControllerActivityProto(proto, SystemProto.GLOBAL_BLUETOOTH_CONTROLLER,
+                getBluetoothControllerActivity(), which);
+
+        // Modem controller (GLOBAL_MODEM_CONTROLLER_DATA)
+        dumpControllerActivityProto(proto, SystemProto.GLOBAL_MODEM_CONTROLLER,
+                getModemControllerActivity(), which);
+
+        // Global network data (GLOBAL_NETWORK_DATA)
+        token = proto.start(SystemProto.GLOBAL_NETWORK);
+        proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_RX,
+                getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which));
+        proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_TX,
+                getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which));
+        proto.write(SystemProto.GlobalNetwork.MOBILE_PACKETS_RX,
+                getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which));
+        proto.write(SystemProto.GlobalNetwork.MOBILE_PACKETS_TX,
+                getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
+        proto.write(SystemProto.GlobalNetwork.WIFI_BYTES_RX,
+                getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
+        proto.write(SystemProto.GlobalNetwork.WIFI_BYTES_TX,
+                getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
+        proto.write(SystemProto.GlobalNetwork.WIFI_PACKETS_RX,
+                getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
+        proto.write(SystemProto.GlobalNetwork.WIFI_PACKETS_TX,
+                getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
+        proto.write(SystemProto.GlobalNetwork.BT_BYTES_RX,
+                getNetworkActivityBytes(NETWORK_BT_RX_DATA, which));
+        proto.write(SystemProto.GlobalNetwork.BT_BYTES_TX,
+                getNetworkActivityBytes(NETWORK_BT_TX_DATA, which));
+        proto.end(token);
+
+        // Wifi controller (GLOBAL_WIFI_CONTROLLER_DATA)
+        dumpControllerActivityProto(proto, SystemProto.GLOBAL_WIFI_CONTROLLER,
+                getWifiControllerActivity(), which);
+
+
+        // Global wifi (GLOBAL_WIFI_DATA)
+        token = proto.start(SystemProto.GLOBAL_WIFI);
+        proto.write(SystemProto.GlobalWifi.ON_DURATION_MS,
+                getWifiOnTime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.GlobalWifi.RUNNING_DURATION_MS,
+                getGlobalWifiRunningTime(rawRealtimeUs, which) / 1000);
+        proto.end(token);
+
+        // Kernel wakelock (KERNEL_WAKELOCK_DATA)
+        final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
+        for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
+            token = proto.start(SystemProto.KERNEL_WAKELOCK);
+            proto.write(SystemProto.KernelWakelock.NAME, ent.getKey());
+            dumpTimer(proto, SystemProto.KernelWakelock.TOTAL, ent.getValue(),
+                    rawRealtimeUs, which);
+            proto.end(token);
+        }
+
+        // Misc (MISC_DATA)
+        // Calculate wakelock times across all uids.
+        long fullWakeLockTimeTotalUs = 0;
+        long partialWakeLockTimeTotalUs = 0;
+
+        final SparseArray<? extends Uid> uidStats = getUidStats();
+        for (int iu = 0; iu < uidStats.size(); iu++) {
+            final Uid u = uidStats.valueAt(iu);
+
+            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks =
+                    u.getWakelockStats();
+            for (int iw = wakelocks.size() - 1; iw >= 0; --iw) {
+                final Uid.Wakelock wl = wakelocks.valueAt(iw);
+
+                final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
+                if (fullWakeTimer != null) {
+                    fullWakeLockTimeTotalUs += fullWakeTimer.getTotalTimeLocked(rawRealtimeUs,
+                            which);
+                }
+
+                final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
+                if (partialWakeTimer != null) {
+                    partialWakeLockTimeTotalUs += partialWakeTimer.getTotalTimeLocked(
+                        rawRealtimeUs, which);
+                }
+            }
+        }
+        token = proto.start(SystemProto.MISC);
+        proto.write(SystemProto.Misc.SCREEN_ON_DURATION_MS,
+                getScreenOnTime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Misc.PHONE_ON_DURATION_MS,
+                getPhoneOnTime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Misc.FULL_WAKELOCK_TOTAL_DURATION_MS,
+                fullWakeLockTimeTotalUs / 1000);
+        proto.write(SystemProto.Misc.PARTIAL_WAKELOCK_TOTAL_DURATION_MS,
+                partialWakeLockTimeTotalUs / 1000);
+        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_DURATION_MS,
+                getMobileRadioActiveTime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_ADJUSTED_TIME_MS,
+                getMobileRadioActiveAdjustedTime(which) / 1000);
+        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_COUNT,
+                getMobileRadioActiveCount(which));
+        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_UNKNOWN_DURATION_MS,
+                getMobileRadioActiveUnknownTime(which) / 1000);
+        proto.write(SystemProto.Misc.INTERACTIVE_DURATION_MS,
+                getInteractiveTime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Misc.BATTERY_SAVER_MODE_ENABLED_DURATION_MS,
+                getPowerSaveModeEnabledTime(rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Misc.NUM_CONNECTIVITY_CHANGES,
+                getNumConnectivityChange(which));
+        proto.write(SystemProto.Misc.DEEP_DOZE_ENABLED_DURATION_MS,
+                getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP, rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Misc.DEEP_DOZE_COUNT,
+                getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
+        proto.write(SystemProto.Misc.DEEP_DOZE_IDLING_DURATION_MS,
+                getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP, rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Misc.DEEP_DOZE_IDLING_COUNT,
+                getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
+        proto.write(SystemProto.Misc.LONGEST_DEEP_DOZE_DURATION_MS,
+                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
+        proto.write(SystemProto.Misc.LIGHT_DOZE_ENABLED_DURATION_MS,
+                getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Misc.LIGHT_DOZE_COUNT,
+                getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
+        proto.write(SystemProto.Misc.LIGHT_DOZE_IDLING_DURATION_MS,
+                getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT, rawRealtimeUs, which) / 1000);
+        proto.write(SystemProto.Misc.LIGHT_DOZE_IDLING_COUNT,
+                getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
+        proto.write(SystemProto.Misc.LONGEST_LIGHT_DOZE_DURATION_MS,
+                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
+        proto.end(token);
+
+        final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
+        helper.create(this);
+        helper.refreshStats(which, UserHandle.USER_ALL);
+
+        // Power use item (POWER_USE_ITEM_DATA)
+        final List<BatterySipper> sippers = helper.getUsageList();
+        if (sippers != null) {
+            for (int i = 0; i < sippers.size(); ++i) {
+                final BatterySipper bs = sippers.get(i);
+                int n = SystemProto.PowerUseItem.UNKNOWN_SIPPER;
+                int uid = 0;
+                switch (bs.drainType) {
+                    case IDLE:
+                        n = SystemProto.PowerUseItem.IDLE;
+                        break;
+                    case CELL:
+                        n = SystemProto.PowerUseItem.CELL;
+                        break;
+                    case PHONE:
+                        n = SystemProto.PowerUseItem.PHONE;
+                        break;
+                    case WIFI:
+                        n = SystemProto.PowerUseItem.WIFI;
+                        break;
+                    case BLUETOOTH:
+                        n = SystemProto.PowerUseItem.BLUETOOTH;
+                        break;
+                    case SCREEN:
+                        n = SystemProto.PowerUseItem.SCREEN;
+                        break;
+                    case FLASHLIGHT:
+                        n = SystemProto.PowerUseItem.FLASHLIGHT;
+                        break;
+                    case APP:
+                        // dumpProtoAppLocked will handle this.
+                        continue;
+                    case USER:
+                        n = SystemProto.PowerUseItem.USER;
+                        uid = UserHandle.getUid(bs.userId, 0);
+                        break;
+                    case UNACCOUNTED:
+                        n = SystemProto.PowerUseItem.UNACCOUNTED;
+                        break;
+                    case OVERCOUNTED:
+                        n = SystemProto.PowerUseItem.OVERCOUNTED;
+                        break;
+                    case CAMERA:
+                        n = SystemProto.PowerUseItem.CAMERA;
+                        break;
+                    case MEMORY:
+                        n = SystemProto.PowerUseItem.MEMORY;
+                        break;
+                }
+                token = proto.start(SystemProto.POWER_USE_ITEM);
+                proto.write(SystemProto.PowerUseItem.NAME, n);
+                proto.write(SystemProto.PowerUseItem.UID, uid);
+                proto.write(SystemProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah);
+                proto.write(SystemProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide);
+                proto.write(SystemProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah);
+                proto.write(SystemProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH,
+                        bs.proportionalSmearMah);
+                proto.end(token);
+            }
+        }
+
+        // Power use summary (POWER_USE_SUMMARY_DATA)
+        token = proto.start(SystemProto.POWER_USE_SUMMARY);
+        proto.write(SystemProto.PowerUseSummary.BATTERY_CAPACITY_MAH,
+                helper.getPowerProfile().getBatteryCapacity());
+        proto.write(SystemProto.PowerUseSummary.COMPUTED_POWER_MAH, helper.getComputedPower());
+        proto.write(SystemProto.PowerUseSummary.MIN_DRAINED_POWER_MAH, helper.getMinDrainedPower());
+        proto.write(SystemProto.PowerUseSummary.MAX_DRAINED_POWER_MAH, helper.getMaxDrainedPower());
+        proto.end(token);
+
+        // RPM stats (RESOURCE_POWER_MANAGER_DATA)
+        final Map<String, ? extends Timer> rpmStats = getRpmStats();
+        final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats();
+        for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) {
+            token = proto.start(SystemProto.RESOURCE_POWER_MANAGER);
+            proto.write(SystemProto.ResourcePowerManager.NAME, ent.getKey());
+            dumpTimer(proto, SystemProto.ResourcePowerManager.TOTAL,
+                    ent.getValue(), rawRealtimeUs, which);
+            dumpTimer(proto, SystemProto.ResourcePowerManager.SCREEN_OFF,
+                    screenOffRpmStats.get(ent.getKey()), rawRealtimeUs, which);
+            proto.end(token);
+        }
+
+        // Screen brightness (SCREEN_BRIGHTNESS_DATA)
+        for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; ++i) {
+            token = proto.start(SystemProto.SCREEN_BRIGHTNESS);
+            proto.write(SystemProto.ScreenBrightness.NAME, i);
+            dumpTimer(proto, SystemProto.ScreenBrightness.TOTAL, getScreenBrightnessTimer(i),
+                    rawRealtimeUs, which);
+            proto.end(token);
+        }
+
+        // Signal scanning time (SIGNAL_SCANNING_TIME_DATA)
+        dumpTimer(proto, SystemProto.SIGNAL_SCANNING, getPhoneSignalScanningTimer(), rawRealtimeUs,
+                which);
+
+        // Phone signal strength (SIGNAL_STRENGTH_TIME_DATA and SIGNAL_STRENGTH_COUNT_DATA)
+        for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; ++i) {
+            token = proto.start(SystemProto.PHONE_SIGNAL_STRENGTH);
+            proto.write(SystemProto.PhoneSignalStrength.NAME, i);
+            dumpTimer(proto, SystemProto.PhoneSignalStrength.TOTAL, getPhoneSignalStrengthTimer(i),
+                    rawRealtimeUs, which);
+            proto.end(token);
+        }
+
+        // Wakeup reasons (WAKEUP_REASON_DATA)
+        final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
+        for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
+            token = proto.start(SystemProto.WAKEUP_REASON);
+            proto.write(SystemProto.WakeupReason.NAME, ent.getKey());
+            dumpTimer(proto, SystemProto.WakeupReason.TOTAL, ent.getValue(), rawRealtimeUs, which);
+            proto.end(token);
+        }
+
+        // Wifi signal strength (WIFI_SIGNAL_STRENGTH_TIME_DATA and WIFI_SIGNAL_STRENGTH_COUNT_DATA)
+        for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; ++i) {
+            token = proto.start(SystemProto.WIFI_SIGNAL_STRENGTH);
+            proto.write(SystemProto.WifiSignalStrength.NAME, i);
+            dumpTimer(proto, SystemProto.WifiSignalStrength.TOTAL, getWifiSignalStrengthTimer(i),
+                    rawRealtimeUs, which);
+            proto.end(token);
+        }
+
+        // Wifi state (WIFI_STATE_TIME_DATA and WIFI_STATE_COUNT_DATA)
+        for (int i = 0; i < NUM_WIFI_STATES; ++i) {
+            token = proto.start(SystemProto.WIFI_STATE);
+            proto.write(SystemProto.WifiState.NAME, i);
+            dumpTimer(proto, SystemProto.WifiState.TOTAL, getWifiStateTimer(i),
+                    rawRealtimeUs, which);
+            proto.end(token);
+        }
+
+        // Wifi supplicant state (WIFI_SUPPL_STATE_TIME_DATA and WIFI_SUPPL_STATE_COUNT_DATA)
+        for (int i = 0; i < NUM_WIFI_SUPPL_STATES; ++i) {
+            token = proto.start(SystemProto.WIFI_SUPPLICANT_STATE);
+            proto.write(SystemProto.WifiSupplicantState.NAME, i);
+            dumpTimer(proto, SystemProto.WifiSupplicantState.TOTAL, getWifiSupplStateTimer(i),
+                    rawRealtimeUs, which);
+            proto.end(token);
+        }
+
+        proto.end(sToken);
+    }
 }
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index b46c6b1..017c213 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1748,22 +1748,26 @@
     public static final int MEMINFO_SHMEM = 4;
     /** @hide */
     public static final int MEMINFO_SLAB = 5;
+     /** @hide */
+    public static final int MEMINFO_SLAB_RECLAIMABLE = 6;
+     /** @hide */
+    public static final int MEMINFO_SLAB_UNRECLAIMABLE = 7;
     /** @hide */
-    public static final int MEMINFO_SWAP_TOTAL = 6;
+    public static final int MEMINFO_SWAP_TOTAL = 8;
     /** @hide */
-    public static final int MEMINFO_SWAP_FREE = 7;
+    public static final int MEMINFO_SWAP_FREE = 9;
     /** @hide */
-    public static final int MEMINFO_ZRAM_TOTAL = 8;
+    public static final int MEMINFO_ZRAM_TOTAL = 10;
     /** @hide */
-    public static final int MEMINFO_MAPPED = 9;
+    public static final int MEMINFO_MAPPED = 11;
     /** @hide */
-    public static final int MEMINFO_VM_ALLOC_USED = 10;
+    public static final int MEMINFO_VM_ALLOC_USED = 12;
     /** @hide */
-    public static final int MEMINFO_PAGE_TABLES = 11;
+    public static final int MEMINFO_PAGE_TABLES = 13;
     /** @hide */
-    public static final int MEMINFO_KERNEL_STACK = 12;
+    public static final int MEMINFO_KERNEL_STACK = 14;
     /** @hide */
-    public static final int MEMINFO_COUNT = 13;
+    public static final int MEMINFO_COUNT = 15;
 
     /**
      * Retrieves /proc/meminfo.  outSizes is filled with fields
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index f8f2813..daacc4e 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -45,4 +45,20 @@
      * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
      */
     void informPollAlarmFired();
+
+    /**
+     * Inform statsd what the version and package are for each uid. Note that each array should
+     * have the same number of elements, and version[i] and package[i] correspond to uid[i].
+     */
+    oneway void informAllUidData(in int[] uid, in int[] version, in String[] app);
+
+    /**
+     * Inform statsd what the uid and version are for one app that was updated.
+     */
+    oneway void informOnePackage(in String app, in int uid, in int version);
+
+    /**
+     * Inform stats that an app was removed.
+     */
+    oneway void informOnePackageRemoved(in String app, in int uid);
 }
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index c091420..7f588ad 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -737,7 +737,9 @@
     private void closeWithStatus(int status, String msg) {
         if (mClosed) return;
         mClosed = true;
-        mGuard.close();
+        if (mGuard != null) {
+            mGuard.close();
+        }
         // Status MUST be sent before closing actual descriptor
         writeCommStatusAndClose(status, msg);
         IoUtils.closeQuietly(mFd);
diff --git a/core/java/android/os/PatternMatcher.java b/core/java/android/os/PatternMatcher.java
index 1f3a1e6..76b2142 100644
--- a/core/java/android/os/PatternMatcher.java
+++ b/core/java/android/os/PatternMatcher.java
@@ -16,7 +16,7 @@
 
 package android.os;
 
-import android.util.Log;
+import android.util.proto.ProtoOutputStream;
 
 import java.util.Arrays;
 
@@ -131,7 +131,17 @@
         }
         return "PatternMatcher{" + type + mPattern + "}";
     }
-    
+
+    /** @hide */
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+        long token = proto.start(fieldId);
+        proto.write(PatternMatcherProto.PATTERN, mPattern);
+        proto.write(PatternMatcherProto.TYPE, mType);
+        // PatternMatcherProto.PARSED_PATTERN is too much to dump, but the field is reserved to
+        // match the current data structure.
+        proto.end(token);
+    }
+
     public int describeContents() {
         return 0;
     }
@@ -141,7 +151,7 @@
         dest.writeInt(mType);
         dest.writeIntArray(mParsedPattern);
     }
-    
+
     public PatternMatcher(Parcel src) {
         mPattern = src.readString();
         mType = src.readInt();
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 430a5e3..8c68871 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -574,6 +574,25 @@
     public static final String DISALLOW_CREATE_WINDOWS = "no_create_windows";
 
     /**
+     * Specifies that system error dialogs for crashed or unresponsive apps should not be shown.
+     * In this case, the system will force-stop the app as if the user chooses the "close app"
+     * option on the UI. No feedback report will be collected as there is no way for the user to
+     * provide explicit consent.
+     *
+     * When this user restriction is set by device owners, it's applied to all users; when it's set
+     * by profile owners, it's only applied to the relevant profiles.
+     * The default value is <code>false</code>.
+     *
+     * <p>This user restriction has no effect on managed profiles.
+     * <p>Key for user restrictions.
+     * <p>Type: Boolean
+     * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+     * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+     * @see #getUserRestrictions()
+     */
+    public static final String DISALLOW_SYSTEM_ERROR_DIALOGS = "no_system_error_dialogs";
+
+    /**
      * Specifies if what is copied in the clipboard of this profile can
      * be pasted in related profiles. Does not restrict if the clipboard of related profiles can be
      * pasted in this profile.
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index ee8eed1..3d2e1d1 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -206,8 +206,7 @@
                     try {
                         mRingtone.setAudioAttributes(new AudioAttributes.Builder(mRingtone
                                 .getAudioAttributes())
-                                .setFlags(AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY |
-                                        AudioAttributes.FLAG_BYPASS_MUTE)
+                                .setFlags(AudioAttributes.FLAG_BYPASS_MUTE)
                                 .build());
                         mRingtone.play();
                     } catch (Throwable e) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a062db4..53e8881 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6792,14 +6792,6 @@
                 "lock_screen_show_notifications";
 
         /**
-         * This preference stores the last stack active task time for each user, which affects what
-         * tasks will be visible in Overview.
-         * @hide
-         */
-        public static final String OVERVIEW_LAST_STACK_ACTIVE_TIME =
-                "overview_last_stack_active_time";
-
-        /**
          * List of TV inputs that are currently hidden. This is a string
          * containing the IDs of all hidden TV inputs. Each ID is encoded by
          * {@link android.net.Uri#encode(String)} and separated by ':'.
@@ -9575,6 +9567,22 @@
         public static final String DEVICE_POLICY_CONSTANTS = "device_policy_constants";
 
         /**
+         * TextClassifier specific settings.
+         * This is encoded as a key=value list, separated by commas. Ex:
+         *
+         * <pre>
+         * smart_selection_dark_launch              (boolean)
+         * smart_selection_enabled_for_edit_text    (boolean)
+         * </pre>
+         *
+         * <p>
+         * Type: string
+         * @hide
+         * see also android.view.textclassifier.TextClassifierConstants
+         */
+        public static final String TEXT_CLASSIFIER_CONSTANTS = "text_classifier_constants";
+
+        /**
          * Get the key that retrieves a bluetooth headset's priority.
          * @hide
          */
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 2e59f6c..953501c 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -65,7 +65,7 @@
  *   <li>The service replies through {@link FillCallback#onSuccess(FillResponse)}.
  *   <li>The Android System calls {@link #onDisconnected()} and unbinds from the
  *       {@code AutofillService}.
- *   <li>The Android System displays an UI affordance with the options sent by the service.
+ *   <li>The Android System displays an autofill UI with the options sent by the service.
  *   <li>The user picks an option.
  *   <li>The proper views are autofilled.
  * </ol>
@@ -365,6 +365,81 @@
  * <p><b>Note:</b> The autofill service could also whitelist well-known browser apps and skip the
  * verifications above, as long as the service can verify the authenticity of the browser app by
  * checking its signing certificate.
+ *
+ * <a name="MultipleStepsSave"></a>
+ * <h3>Saving when data is split in multiple screens</h3>
+ *
+ * Apps often split the user data in multiple screens in the same activity, specially in
+ * activities used to create a new user account. For example, the first screen asks for a username,
+ * and if the username is available, it moves to a second screen, which asks for a password.
+ *
+ * <p>It's tricky to handle save for autofill in these situations, because the autofill service must
+ * wait until the user enters both fields before the autofill save UI can be shown. But it can be
+ * done by following the steps below:
+ *
+ * <ol>
+ * <li>In the first
+ * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback) fill request}, the service
+ * adds a {@link FillResponse.Builder#setClientState(android.os.Bundle) client state bundle} in
+ * the response, containing the autofill ids of the partial fields present in the screen.
+ * <li>In the second
+ * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback) fill request}, the service
+ * retrieves the {@link FillRequest#getClientState() client state bundle}, gets the autofill ids
+ * set in the previous request from the client state, and adds these ids and the
+ * {@link SaveInfo#FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} to the {@link SaveInfo} used in the second
+ * response.
+ * <li>In the {@link #onSaveRequest(SaveRequest, SaveCallback) save request}, the service uses the
+ * proper {@link FillContext fill contexts} to get the value of each field (there is one fill
+ * context per fill request).
+ * </ol>
+ *
+ * <p>For example, in an app that uses 2 steps for the username and password fields, the workflow
+ * would be:
+ * <pre class="prettyprint">
+ *  // On first fill request
+ *  AutofillId usernameId = // parse from AssistStructure;
+ *  Bundle clientState = new Bundle();
+ *  clientState.putParcelable("usernameId", usernameId);
+ *  fillCallback.onSuccess(
+ *    new FillResponse.Builder()
+ *        .setClientState(clientState)
+ *        .setSaveInfo(new SaveInfo
+ *             .Builder(SaveInfo.SAVE_DATA_TYPE_USERNAME, new AutofillId[] {usernameId})
+ *             .build())
+ *        .build());
+ *
+ *  // On second fill request
+ *  Bundle clientState = fillRequest.getClientState();
+ *  AutofillId usernameId = clientState.getParcelable("usernameId");
+ *  AutofillId passwordId = // parse from AssistStructure
+ *  clientState.putParcelable("passwordId", passwordId);
+ *  fillCallback.onSuccess(
+ *    new FillResponse.Builder()
+ *        .setClientState(clientState)
+ *        .setSaveInfo(new SaveInfo
+ *             .Builder(SaveInfo.SAVE_DATA_TYPE_USERNAME | SaveInfo.SAVE_DATA_TYPE_PASSWORD,
+ *                      new AutofillId[] {usernameId, passwordId})
+ *             .setFlags(SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE)
+ *             .build())
+ *        .build());
+ *
+ *  // On save request
+ *  Bundle clientState = saveRequest.getClientState();
+ *  AutofillId usernameId = clientState.getParcelable("usernameId");
+ *  AutofillId passwordId = clientState.getParcelable("passwordId");
+ *  List<FillContext> fillContexts = saveRequest.getFillContexts();
+ *
+ *  FillContext usernameContext = fillContexts.get(0);
+ *  ViewNode usernameNode = findNodeByAutofillId(usernameContext.getStructure(), usernameId);
+ *  AutofillValue username = usernameNode.getAutofillValue().getTextValue().toString();
+ *
+ *  FillContext passwordContext = fillContexts.get(1);
+ *  ViewNode passwordNode = findNodeByAutofillId(passwordContext.getStructure(), passwordId);
+ *  AutofillValue password = passwordNode.getAutofillValue().getTextValue().toString();
+ *
+ *  save(username, password);
+ *
+ * </pre>
  */
 public abstract class AutofillService extends Service {
     private static final String TAG = "AutofillService";
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 1b9240c..fde2416 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -68,7 +68,7 @@
  *       .build();
  * </pre>
  *
- * <p>The save type flags are used to display the appropriate strings in the save UI affordance.
+ * <p>The save type flags are used to display the appropriate strings in the autofill save UI.
  * You can pass multiple values, but try to keep it short if possible. In the above example, just
  * {@code SaveInfo.SAVE_DATA_TYPE_PASSWORD} would be enough.
  *
@@ -103,13 +103,17 @@
  *       .build();
  * </pre>
  *
+ * <a name="TriggeringSaveRequest"></a>
+ * <h3>Triggering a save request</h3>
+ *
  * <p>The {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)} can be triggered after
  * any of the following events:
  * <ul>
  *   <li>The {@link Activity} finishes.
- *   <li>The app explicitly called {@link AutofillManager#commit()}.
- *   <li>All required views became invisible (if the {@link SaveInfo} was created with the
+ *   <li>The app explicitly calls {@link AutofillManager#commit()}.
+ *   <li>All required views become invisible (if the {@link SaveInfo} was created with the
  *       {@link #FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} flag).
+ *   <li>The user clicks a specific view (defined by {@link Builder#setTriggerId(AutofillId)}.
  * </ul>
  *
  * <p>But it is only triggered when all conditions below are met:
@@ -123,10 +127,13 @@
  *   <li>There is no {@link Dataset} in the last {@link FillResponse} that completely matches the
  *       screen state (i.e., all required and optional fields in the dataset have the same value as
  *       the fields in the screen).
- *   <li>The user explicitly tapped the UI affordance asking to save data for autofill.
+ *   <li>The user explicitly tapped the autofill save UI asking to save data for autofill.
  * </ul>
  *
- * <p>The service can also customize some aspects of the save UI affordance:
+ * <a name="CustomizingSaveUI"></a>
+ * <h3>Customizing the autofill save UI</h3>
+ *
+ * <p>The service can also customize some aspects of the autofill save UI:
  * <ul>
  *   <li>Add a simple subtitle by calling {@link Builder#setDescription(CharSequence)}.
  *   <li>Add a customized subtitle by calling
@@ -212,16 +219,25 @@
     @interface SaveDataType{}
 
     /**
-     * Usually {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)}
-     * is called once the {@link Activity} finishes. If this flag is set it is called once all
-     * saved views become invisible.
+     * Usually, a save request is only automatically <a href="#TriggeringSaveRequest">triggered</a>
+     * once the {@link Activity} finishes. If this flag is set, it is triggered once all saved views
+     * become invisible.
      */
     public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 0x1;
 
+    /**
+     * By default, a save request is automatically <a href="#TriggeringSaveRequest">triggered</a>
+     * once the {@link Activity} finishes. If this flag is set, finishing the activity doesn't
+     * trigger a save request.
+     *
+     * <p>This flag is typically used in conjunction with {@link Builder#setTriggerId(AutofillId)}.
+     */
+    public static final int FLAG_DONT_SAVE_ON_FINISH = 0x2;
+
     /** @hide */
     @IntDef(
             flag = true,
-            value = {FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE})
+            value = {FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE, FLAG_DONT_SAVE_ON_FINISH})
     @Retention(RetentionPolicy.SOURCE)
     @interface SaveInfoFlags{}
 
@@ -236,6 +252,7 @@
     private final InternalValidator mValidator;
     private final InternalSanitizer[] mSanitizerKeys;
     private final AutofillId[][] mSanitizerValues;
+    private final AutofillId mTriggerId;
 
     private SaveInfo(Builder builder) {
         mType = builder.mType;
@@ -259,6 +276,7 @@
                 mSanitizerValues[i] = builder.mSanitizers.valueAt(i);
             }
         }
+        mTriggerId = builder.mTriggerId;
     }
 
     /** @hide */
@@ -320,6 +338,12 @@
         return mSanitizerValues;
     }
 
+    /** @hide */
+    @Nullable
+    public AutofillId getTriggerId() {
+        return mTriggerId;
+    }
+
     /**
      * A builder for {@link SaveInfo} objects.
      */
@@ -338,6 +362,7 @@
         private ArrayMap<InternalSanitizer, AutofillId[]> mSanitizers;
         // Set used to validate against duplicate ids.
         private ArraySet<AutofillId> mSanitizerIds;
+        private AutofillId mTriggerId;
 
         /**
          * Creates a new builder.
@@ -394,13 +419,15 @@
         /**
          * Sets flags changing the save behavior.
          *
-         * @param flags {@link #FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} or {@code 0}.
+         * @param flags {@link #FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE},
+         * {@link #FLAG_DONT_SAVE_ON_FINISH}, or {@code 0}.
          * @return This builder.
          */
         public @NonNull Builder setFlags(@SaveInfoFlags int flags) {
             throwIfDestroyed();
 
-            mFlags = Preconditions.checkFlagsArgument(flags, FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE);
+            mFlags = Preconditions.checkFlagsArgument(flags,
+                    FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE | FLAG_DONT_SAVE_ON_FINISH);
             return this;
         }
 
@@ -493,8 +520,8 @@
         }
 
         /**
-         * Sets an object used to validate the user input - if the input is not valid, the Save UI
-         * affordance is not shown.
+         * Sets an object used to validate the user input - if the input is not valid, the
+         * autofill save UI is not shown.
          *
          * <p>Typically used to validate credit card numbers. Examples:
          *
@@ -520,7 +547,7 @@
          *   );
          * </pre>
          *
-         * <p><b>NOTE: </b>the example above is just for illustrative purposes; the same validator
+         * <p><b>Note:</b> the example above is just for illustrative purposes; the same validator
          * could be created using a single regex for the {@code OR} part:
          *
          * <pre class="prettyprint">
@@ -615,6 +642,27 @@
             return this;
         }
 
+       /**
+         * Explicitly defines the view that should commit the autofill context when clicked.
+         *
+         * <p>Usually, the save request is only automatically
+         * <a href="#TriggeringSaveRequest">triggered</a> after the activity is
+         * finished or all relevant views become invisible, but there are scenarios where the
+         * autofill context is automatically commited too late
+         * &mdash;for example, when the activity manually clears the autofillable views when a
+         * button is tapped. This method can be used to trigger the autofill save UI earlier in
+         * these scenarios.
+         *
+         * <p><b>Note:</b> This method should only be used in scenarios where the automatic workflow
+         * is not enough, otherwise it could trigger the autofill save UI when it should not&mdash;
+         * for example, when the user entered invalid credentials for the autofillable views.
+         */
+        public @NonNull Builder setTriggerId(@NonNull AutofillId id) {
+            throwIfDestroyed();
+            mTriggerId = Preconditions.checkNotNull(id);
+            return this;
+        }
+
         /**
          * Builds a new {@link SaveInfo} instance.
          *
@@ -652,13 +700,14 @@
                 .append(", description=").append(mDescription)
                 .append(DebugUtils.flagsToString(SaveInfo.class, "NEGATIVE_BUTTON_STYLE_",
                         mNegativeButtonStyle))
-                .append(", mFlags=").append(mFlags)
-                .append(", mCustomDescription=").append(mCustomDescription)
-                .append(", validation=").append(mValidator)
+                .append(", flags=").append(mFlags)
+                .append(", customDescription=").append(mCustomDescription)
+                .append(", validator=").append(mValidator)
                 .append(", sanitizerKeys=")
                     .append(mSanitizerKeys == null ? "N/A:" : mSanitizerKeys.length)
                 .append(", sanitizerValues=")
                     .append(mSanitizerValues == null ? "N/A:" : mSanitizerValues.length)
+                .append(", triggerId=").append(mTriggerId)
                 .append("]").toString();
     }
 
@@ -687,6 +736,7 @@
                 parcel.writeParcelableArray(mSanitizerValues[i], flags);
             }
         }
+        parcel.writeParcelable(mTriggerId, flags);
         parcel.writeInt(mFlags);
     }
 
@@ -727,6 +777,10 @@
                     builder.addSanitizer(sanitizers[i], autofillIds);
                 }
             }
+            final AutofillId triggerId = parcel.readParcelable(null);
+            if (triggerId != null) {
+                builder.setTriggerId(triggerId);
+            }
             builder.setFlags(parcel.readInt());
             return builder.build();
         }
diff --git a/core/java/android/service/autofill/SaveRequest.java b/core/java/android/service/autofill/SaveRequest.java
index 65fdb5c..f53967b 100644
--- a/core/java/android/service/autofill/SaveRequest.java
+++ b/core/java/android/service/autofill/SaveRequest.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Bundle;
-import android.os.CancellationSignal;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -60,9 +59,14 @@
     }
 
     /**
-     * Gets the extra client state returned from the last {@link
-     * AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)}
-     * fill request}.
+     * Gets the latest client state extra returned from the service.
+     *
+     * <p><b>Note:</b> Prior to Android {@link android.os.Build.VERSION_CODES#P}, only client state
+     * bundles set by {@link FillResponse.Builder#setClientState(Bundle)} where considered. On
+     * Android {@link android.os.Build.VERSION_CODES#P} and higher, bundles set in the result of
+     * an authenticated request through the
+     * {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE} extra are
+     * also considered (and take precedence when set).
      *
      * @return The client state.
      */
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 7bec898..c5615ae 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -76,10 +76,13 @@
     private static final int DAY_MINUTES = 24 * 60;
     private static final int ZERO_VALUE_MS = 10 * SECONDS_MS;
 
-    private static final boolean DEFAULT_ALLOW_CALLS = true;
+    // Default allow categories set in readXml() from default_zen_mode_config.xml, fallback values:
+    private static final boolean DEFAULT_ALLOW_ALARMS = true;
+    private static final boolean DEFAULT_ALLOW_MEDIA_SYSTEM_OTHER = true;
+    private static final boolean DEFAULT_ALLOW_CALLS = false;
     private static final boolean DEFAULT_ALLOW_MESSAGES = false;
-    private static final boolean DEFAULT_ALLOW_REMINDERS = true;
-    private static final boolean DEFAULT_ALLOW_EVENTS = true;
+    private static final boolean DEFAULT_ALLOW_REMINDERS = false;
+    private static final boolean DEFAULT_ALLOW_EVENTS = false;
     private static final boolean DEFAULT_ALLOW_REPEAT_CALLERS = false;
     private static final boolean DEFAULT_ALLOW_SCREEN_OFF = true;
     private static final boolean DEFAULT_ALLOW_SCREEN_ON = true;
@@ -89,6 +92,8 @@
     private static final String ZEN_ATT_VERSION = "version";
     private static final String ZEN_ATT_USER = "user";
     private static final String ALLOW_TAG = "allow";
+    private static final String ALLOW_ATT_ALARMS = "alarms";
+    private static final String ALLOW_ATT_MEDIA = "media_system_other";
     private static final String ALLOW_ATT_CALLS = "calls";
     private static final String ALLOW_ATT_REPEAT_CALLERS = "repeatCallers";
     private static final String ALLOW_ATT_MESSAGES = "messages";
@@ -100,8 +105,6 @@
     private static final String ALLOW_ATT_SCREEN_OFF = "visualScreenOff";
     private static final String ALLOW_ATT_SCREEN_ON = "visualScreenOn";
 
-    private static final String CONDITION_TAG = "condition";
-    private static final String CONDITION_ATT_COMPONENT = "component";
     private static final String CONDITION_ATT_ID = "id";
     private static final String CONDITION_ATT_SUMMARY = "summary";
     private static final String CONDITION_ATT_LINE1 = "line1";
@@ -123,6 +126,8 @@
     private static final String RULE_ATT_CREATION_TIME = "creationTime";
     private static final String RULE_ATT_ENABLER = "enabler";
 
+    public boolean allowAlarms = DEFAULT_ALLOW_ALARMS;
+    public boolean allowMediaSystemOther = DEFAULT_ALLOW_MEDIA_SYSTEM_OTHER;
     public boolean allowCalls = DEFAULT_ALLOW_CALLS;
     public boolean allowRepeatCallers = DEFAULT_ALLOW_REPEAT_CALLERS;
     public boolean allowMessages = DEFAULT_ALLOW_MESSAGES;
@@ -161,6 +166,8 @@
         }
         allowWhenScreenOff = source.readInt() == 1;
         allowWhenScreenOn = source.readInt() == 1;
+        allowAlarms = source.readInt() == 1;
+        allowMediaSystemOther = source.readInt() == 1;
     }
 
     @Override
@@ -190,19 +197,23 @@
         }
         dest.writeInt(allowWhenScreenOff ? 1 : 0);
         dest.writeInt(allowWhenScreenOn ? 1 : 0);
+        dest.writeInt(allowAlarms ? 1 : 0);
+        dest.writeInt(allowMediaSystemOther ? 1 : 0);
     }
 
     @Override
     public String toString() {
         return new StringBuilder(ZenModeConfig.class.getSimpleName()).append('[')
                 .append("user=").append(user)
+                .append(",allowAlarms=").append(allowAlarms)
+                .append(",allowMediaSystemOther=").append(allowMediaSystemOther)
+                .append(",allowReminders=").append(allowReminders)
+                .append(",allowEvents=").append(allowEvents)
                 .append(",allowCalls=").append(allowCalls)
                 .append(",allowRepeatCallers=").append(allowRepeatCallers)
                 .append(",allowMessages=").append(allowMessages)
                 .append(",allowCallsFrom=").append(sourceToString(allowCallsFrom))
                 .append(",allowMessagesFrom=").append(sourceToString(allowMessagesFrom))
-                .append(",allowReminders=").append(allowReminders)
-                .append(",allowEvents=").append(allowEvents)
                 .append(",allowWhenScreenOff=").append(allowWhenScreenOff)
                 .append(",allowWhenScreenOn=").append(allowWhenScreenOn)
                 .append(",automaticRules=").append(automaticRules)
@@ -218,9 +229,21 @@
         if (user != to.user) {
             d.addLine("user", user, to.user);
         }
+        if (allowAlarms != to.allowAlarms) {
+            d.addLine("allowAlarms", allowAlarms, to.allowAlarms);
+        }
+        if (allowMediaSystemOther != to.allowMediaSystemOther) {
+            d.addLine("allowMediaSystemOther", allowMediaSystemOther, to.allowMediaSystemOther);
+        }
         if (allowCalls != to.allowCalls) {
             d.addLine("allowCalls", allowCalls, to.allowCalls);
         }
+        if (allowReminders != to.allowReminders) {
+            d.addLine("allowReminders", allowReminders, to.allowReminders);
+        }
+        if (allowEvents != to.allowEvents) {
+            d.addLine("allowEvents", allowEvents, to.allowEvents);
+        }
         if (allowRepeatCallers != to.allowRepeatCallers) {
             d.addLine("allowRepeatCallers", allowRepeatCallers, to.allowRepeatCallers);
         }
@@ -233,12 +256,6 @@
         if (allowMessagesFrom != to.allowMessagesFrom) {
             d.addLine("allowMessagesFrom", allowMessagesFrom, to.allowMessagesFrom);
         }
-        if (allowReminders != to.allowReminders) {
-            d.addLine("allowReminders", allowReminders, to.allowReminders);
-        }
-        if (allowEvents != to.allowEvents) {
-            d.addLine("allowEvents", allowEvents, to.allowEvents);
-        }
         if (allowWhenScreenOff != to.allowWhenScreenOff) {
             d.addLine("allowWhenScreenOff", allowWhenScreenOff, to.allowWhenScreenOff);
         }
@@ -335,7 +352,9 @@
         if (!(o instanceof ZenModeConfig)) return false;
         if (o == this) return true;
         final ZenModeConfig other = (ZenModeConfig) o;
-        return other.allowCalls == allowCalls
+        return other.allowAlarms == allowAlarms
+                && other.allowMediaSystemOther == allowMediaSystemOther
+                && other.allowCalls == allowCalls
                 && other.allowRepeatCallers == allowRepeatCallers
                 && other.allowMessages == allowMessages
                 && other.allowCallsFrom == allowCallsFrom
@@ -351,10 +370,10 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(allowCalls, allowRepeatCallers, allowMessages, allowCallsFrom,
-                allowMessagesFrom, allowReminders, allowEvents, allowWhenScreenOff,
-                allowWhenScreenOn,
-                user, automaticRules, manualRule);
+        return Objects.hash(allowAlarms, allowMediaSystemOther, allowCalls,
+                allowRepeatCallers, allowMessages,
+                allowCallsFrom, allowMessagesFrom, allowReminders, allowEvents,
+                allowWhenScreenOff, allowWhenScreenOn, user, automaticRules, manualRule);
     }
 
     private static String toDayList(int[] days) {
@@ -413,10 +432,12 @@
             }
             if (type == XmlPullParser.START_TAG) {
                 if (ALLOW_TAG.equals(tag)) {
-                    rt.allowCalls = safeBoolean(parser, ALLOW_ATT_CALLS, false);
+                    rt.allowCalls = safeBoolean(parser, ALLOW_ATT_CALLS,
+                            DEFAULT_ALLOW_CALLS);
                     rt.allowRepeatCallers = safeBoolean(parser, ALLOW_ATT_REPEAT_CALLERS,
                             DEFAULT_ALLOW_REPEAT_CALLERS);
-                    rt.allowMessages = safeBoolean(parser, ALLOW_ATT_MESSAGES, false);
+                    rt.allowMessages = safeBoolean(parser, ALLOW_ATT_MESSAGES,
+                            DEFAULT_ALLOW_MESSAGES);
                     rt.allowReminders = safeBoolean(parser, ALLOW_ATT_REMINDERS,
                             DEFAULT_ALLOW_REMINDERS);
                     rt.allowEvents = safeBoolean(parser, ALLOW_ATT_EVENTS, DEFAULT_ALLOW_EVENTS);
@@ -438,6 +459,9 @@
                             safeBoolean(parser, ALLOW_ATT_SCREEN_OFF, DEFAULT_ALLOW_SCREEN_OFF);
                     rt.allowWhenScreenOn =
                             safeBoolean(parser, ALLOW_ATT_SCREEN_ON, DEFAULT_ALLOW_SCREEN_ON);
+                    rt.allowAlarms = safeBoolean(parser, ALLOW_ATT_ALARMS, DEFAULT_ALLOW_ALARMS);
+                    rt.allowMediaSystemOther = safeBoolean(parser, ALLOW_ATT_MEDIA,
+                            DEFAULT_ALLOW_MEDIA_SYSTEM_OTHER);
                 } else if (MANUAL_TAG.equals(tag)) {
                     rt.manualRule = readRuleXml(parser);
                 } else if (AUTOMATIC_TAG.equals(tag)) {
@@ -468,6 +492,8 @@
         out.attribute(null, ALLOW_ATT_MESSAGES_FROM, Integer.toString(allowMessagesFrom));
         out.attribute(null, ALLOW_ATT_SCREEN_OFF, Boolean.toString(allowWhenScreenOff));
         out.attribute(null, ALLOW_ATT_SCREEN_ON, Boolean.toString(allowWhenScreenOn));
+        out.attribute(null, ALLOW_ATT_ALARMS, Boolean.toString(allowAlarms));
+        out.attribute(null, ALLOW_ATT_ALARMS, Boolean.toString(allowMediaSystemOther));
         out.endTag(null, ALLOW_TAG);
 
         if (manualRule != null) {
@@ -654,6 +680,12 @@
         if (!allowWhenScreenOn) {
             suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_SCREEN_ON;
         }
+        if (allowAlarms) {
+            priorityCategories |= Policy.PRIORITY_CATEGORY_ALARMS;
+        }
+        if (allowMediaSystemOther) {
+            priorityCategories |= Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER;
+        }
         priorityCallSenders = sourceToPrioritySenders(allowCallsFrom, priorityCallSenders);
         priorityMessageSenders = sourceToPrioritySenders(allowMessagesFrom, priorityMessageSenders);
         return new Policy(priorityCategories, priorityCallSenders, priorityMessageSenders,
@@ -680,10 +712,13 @@
 
     public void applyNotificationPolicy(Policy policy) {
         if (policy == null) return;
-        allowCalls = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_CALLS) != 0;
-        allowMessages = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MESSAGES) != 0;
+        allowAlarms = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_ALARMS) != 0;
+        allowMediaSystemOther = (policy.priorityCategories
+                & Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) != 0;
         allowEvents = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_EVENTS) != 0;
         allowReminders = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_REMINDERS) != 0;
+        allowCalls = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_CALLS) != 0;
+        allowMessages = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MESSAGES) != 0;
         allowRepeatCallers = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_REPEAT_CALLERS)
                 != 0;
         allowCallsFrom = prioritySendersToSource(policy.priorityCallSenders, allowCallsFrom);
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index 24260c4..fba358c 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -299,7 +299,7 @@
 
         private final Paint.FontMetricsInt mFontMetricsInt = new Paint.FontMetricsInt();
 
-        private static final SynchronizedPool<Builder> sPool = new SynchronizedPool<Builder>(3);
+        private static final SynchronizedPool<Builder> sPool = new SynchronizedPool<>(3);
     }
 
     /**
@@ -440,7 +440,7 @@
             mEllipsizeAt = null;
         }
 
-        mObjects = new PackedObjectVector<Directions>(1);
+        mObjects = new PackedObjectVector<>(1);
 
         // Initial state is a single line with 0 characters (0 to 0), with top at 0 and bottom at
         // whatever is natural, and undefined ellipsis.
@@ -1050,7 +1050,7 @@
 
     private static class ChangeWatcher implements TextWatcher, SpanWatcher {
         public ChangeWatcher(DynamicLayout layout) {
-            mLayout = new WeakReference<DynamicLayout>(layout);
+            mLayout = new WeakReference<>(layout);
         }
 
         private void reflow(CharSequence s, int where, int before, int after) {
diff --git a/core/java/android/text/Hyphenator.java b/core/java/android/text/Hyphenator.java
index ad26f23..ddfc00c 100644
--- a/core/java/android/text/Hyphenator.java
+++ b/core/java/android/text/Hyphenator.java
@@ -129,7 +129,6 @@
             final String patternFilename = "hyph-" + languageTag.toLowerCase(Locale.US) + ".hyb";
             final File patternFile = new File(SYSTEM_HYPHENATOR_LOCATION, patternFilename);
             if (!patternFile.canRead()) {
-                Log.e(TAG, "hyphenation patterns for " + patternFile + " not found or unreadable");
                 mDataAddress = 0;
             } else {
                 long address;
@@ -230,6 +229,11 @@
             loadData("tk", 2, 2); // Turkmen
             loadData("und-Ethi", 1, 1); // Any language in Ethiopic script
 
+            // Following two hyphenators do not have pattern files but there is some special logic
+            // based on language.
+            loadData("ca", 2, 2);  // Catalan
+            loadData("pl", 2, 2);  // Polish
+
             // English locales that fall back to en-US. The data is
             // from CLDR. It's all English locales, minus the locales whose
             // parent is en-001 (from supplementalData.xml, under <parentLocales>).
@@ -267,7 +271,7 @@
         }
     };
 
-    private static native long nBuildHyphenator(/* non-zero */ long dataAddress,
+    private static native long nBuildHyphenator(long dataAddress,
             @NonNull String langTag, @IntRange(from = 1) int minPrefix,
             @IntRange(from = 1) int minSuffix);
 }
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 60fff73..ac5c2e9 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -319,8 +319,6 @@
 
     private float getJustifyWidth(int lineNum) {
         Alignment paraAlign = mAlignment;
-        TabStops tabStops = null;
-        boolean tabStopsIsInitialized = false;
 
         int left = 0;
         int right = mWidth;
@@ -371,10 +369,6 @@
             }
         }
 
-        if (getLineContainsTab(lineNum)) {
-            tabStops = new TabStops(TAB_INCREMENT, spans);
-        }
-
         final Alignment align;
         if (paraAlign == Alignment.ALIGN_LEFT) {
             align = (dir == DIR_LEFT_TO_RIGHT) ?  Alignment.ALIGN_NORMAL : Alignment.ALIGN_OPPOSITE;
@@ -1423,7 +1417,6 @@
         float dist = Math.abs(getHorizontal(max, primary) - horiz);
 
         if (dist <= bestdist) {
-            bestdist = dist;
             best = max;
         }
 
@@ -1570,7 +1563,7 @@
         // XXX: we don't care about tabs
         tl.set(mPaint, mText, lineStart, lineEnd, lineDir, directions, false, null);
         caret = lineStart + tl.getOffsetToLeftRightOf(caret - lineStart, toLeft);
-        tl = TextLine.recycle(tl);
+        TextLine.recycle(tl);
         return caret;
     }
 
@@ -1894,10 +1887,7 @@
 
         int margin = 0;
 
-        boolean isFirstParaLine = lineStart == 0 ||
-            spanned.charAt(lineStart - 1) == '\n';
-
-        boolean useFirstLineMargin = isFirstParaLine;
+        boolean useFirstLineMargin = lineStart == 0 || spanned.charAt(lineStart - 1) == '\n';
         for (int i = 0; i < spans.length; i++) {
             if (spans[i] instanceof LeadingMarginSpan2) {
                 int spStart = spanned.getSpanStart(spans[i]);
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 961cd8ee..4b6b6ae 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -433,7 +433,6 @@
          *    + addStyleRun (a text run, to be measured in native code)
          *    + addReplacementRun (a replacement run, width is given)
          *
-         * After measurement, nGetWidths() is valid if the widths are needed (eg for ellipsis).
          * Run nComputeLineBreaks() to obtain line breaks for the paragraph.
          *
          * After all paragraphs, call finish() to release expensive buffers.
@@ -441,8 +440,6 @@
 
         private Pair<String, long[]> getLocaleAndHyphenatorIfChanged(TextPaint paint) {
             final LocaleList locales = paint.getTextLocales();
-            final String languageTags;
-            long[] hyphenators;
             if (!locales.equals(mLocales)) {
                 mLocales = locales;
                 return new Pair(locales.toLanguageTags(), getHyphenators(locales));
@@ -521,7 +518,7 @@
 
         private LocaleList mLocales;
 
-        private static final SynchronizedPool<Builder> sPool = new SynchronizedPool<Builder>(3);
+        private static final SynchronizedPool<Builder> sPool = new SynchronizedPool<>(3);
     }
 
     public StaticLayout(CharSequence source, TextPaint paint,
@@ -866,10 +863,9 @@
                 spanEndCacheCount++;
             }
 
-            nGetWidths(b.mNativePtr, widths);
             int breakCount = nComputeLineBreaks(b.mNativePtr, lineBreaks, lineBreaks.breaks,
                     lineBreaks.widths, lineBreaks.ascents, lineBreaks.descents, lineBreaks.flags,
-                    lineBreaks.breaks.length);
+                    lineBreaks.breaks.length, widths);
 
             final int[] breaks = lineBreaks.breaks;
             final float[] lineWidths = lineBreaks.widths;
@@ -947,10 +943,10 @@
                     boolean moreChars = (endPos < bufEnd);
 
                     final int ascent = fallbackLineSpacing
-                            ? Math.min(fmAscent, (int) Math.round(ascents[breakIndex]))
+                            ? Math.min(fmAscent, Math.round(ascents[breakIndex]))
                             : fmAscent;
                     final int descent = fallbackLineSpacing
-                            ? Math.max(fmDescent, (int) Math.round(descents[breakIndex]))
+                            ? Math.max(fmDescent, Math.round(descents[breakIndex]))
                             : fmDescent;
                     v = out(source, here, endPos,
                             ascent, descent, fmTop, fmBottom,
@@ -1177,7 +1173,7 @@
         mWorkPaint.set(paint);
         do {
             final float ellipsizedWidth = guessEllipsis(text, lineStart, lineEnd, widths,
-                    widthStart, tempAvail, where, line, textWidth, mWorkPaint, forceEllipsis, dir);
+                    widthStart, tempAvail, where, line, mWorkPaint, forceEllipsis, dir);
             if (ellipsizedWidth <= avail) {
                 lineFits = true;
             } else {
@@ -1207,7 +1203,7 @@
     // This method temporarily modifies the TextPaint passed to it, so the TextPaint passed to it
     // should not be accessed while the method is running.
     private float guessEllipsis(CharSequence text, int lineStart, int lineEnd, float[] widths,
-            int widthStart, float avail, TextUtils.TruncateAt where, int line, float textWidth,
+            int widthStart, float avail, TextUtils.TruncateAt where, int line,
             TextPaint paint, boolean forceEllipsis, int dir) {
         final int savedHyphenEdit = paint.getHyphenEdit();
         paint.setHyphenEdit(0);
@@ -1551,16 +1547,17 @@
             @FloatRange(from = 0.0f) float width, @Nullable String languageTags,
             @Nullable long[] hyphenators);
 
-    private static native void nGetWidths(long nativePtr, float[] widths);
-
     // populates LineBreaks and returns the number of breaks found
     //
     // the arrays inside the LineBreaks objects are passed in as well
     // to reduce the number of JNI calls in the common case where the
     // arrays do not have to be resized
+    // The individual character widths will be returned in charWidths. The length of charWidths must
+    // be at least the length of the text.
     private static native int nComputeLineBreaks(long nativePtr, LineBreaks recycle,
             int[] recycleBreaks, float[] recycleWidths, float[] recycleAscents,
-            float[] recycleDescents, int[] recycleFlags, int recycleLength);
+            float[] recycleDescents, int[] recycleFlags, int recycleLength,
+            float[] charWidths);
 
     private int mLineCount;
     private int mTopPadding, mBottomPadding;
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 2dbff10..20c0ed8 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -73,7 +73,7 @@
             new SpanSet<ReplacementSpan>(ReplacementSpan.class);
 
     private final DecorationInfo mDecorationInfo = new DecorationInfo();
-    private final ArrayList<DecorationInfo> mDecorations = new ArrayList();
+    private final ArrayList<DecorationInfo> mDecorations = new ArrayList<>();
 
     private static final TextLine[] sCached = new TextLine[3];
 
@@ -340,14 +340,14 @@
 
                     boolean advance = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
                     if (inSegment && advance) {
-                        return h += measureRun(segstart, offset, j, runIsRtl, fmi);
+                        return h + measureRun(segstart, offset, j, runIsRtl, fmi);
                     }
 
                     float w = measureRun(segstart, j, j, runIsRtl, fmi);
                     h += advance ? w : -w;
 
                     if (inSegment) {
-                        return h += measureRun(segstart, offset, j, runIsRtl, null);
+                        return h + measureRun(segstart, offset, j, runIsRtl, null);
                     }
 
                     if (codept == '\t') {
@@ -828,14 +828,14 @@
                     }
                     if (info.isUnderlineText) {
                         final float thickness =
-                                Math.max(((Paint) wp).getUnderlineThickness(), 1.0f);
+                                Math.max(wp.getUnderlineThickness(), 1.0f);
                         drawStroke(wp, c, wp.getColor(), wp.getUnderlinePosition(), thickness,
                                 decorationXLeft, decorationXRight, y);
                     }
 
                     if (info.isStrikeThruText) {
                         final float thickness =
-                                Math.max(((Paint) wp).getStrikeThruThickness(), 1.0f);
+                                Math.max(wp.getStrikeThruThickness(), 1.0f);
                         drawStroke(wp, c, wp.getColor(), wp.getStrikeThruPosition(), thickness,
                                 decorationXLeft, decorationXRight, y);
                     }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 31daeff..5482589 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -21,15 +21,22 @@
 import android.annotation.Size;
 import android.graphics.Bitmap;
 import android.graphics.GraphicBuffer;
+import android.graphics.Point;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
+import android.os.Debug;
 import android.os.IBinder;
 import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
 
 import dalvik.system.CloseGuard;
 
+import java.io.Closeable;
+
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * SurfaceControl
  *  @hide
@@ -54,25 +61,34 @@
             Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
             boolean allLayers, boolean useIdentityTransform);
 
-    private static native void nativeOpenTransaction();
-    private static native void nativeCloseTransaction(boolean sync);
-    private static native void nativeSetAnimationTransaction();
+    private static native long nativeCreateTransaction();
+    private static native long nativeGetNativeTransactionFinalizer();
+    private static native void nativeApplyTransaction(long transactionObj, boolean sync);
+    private static native void nativeSetAnimationTransaction(long transactionObj);
 
-    private static native void nativeSetLayer(long nativeObject, int zorder);
-    private static native void nativeSetRelativeLayer(long nativeObject, IBinder relativeTo,
-            int zorder);
-    private static native void nativeSetPosition(long nativeObject, float x, float y);
-    private static native void nativeSetGeometryAppliesWithResize(long nativeObject);
-    private static native void nativeSetSize(long nativeObject, int w, int h);
-    private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
-    private static native void nativeSetAlpha(long nativeObject, float alpha);
-    private static native void nativeSetColor(long nativeObject, float[] color);
-    private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx,
+    private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
+    private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
+            IBinder relativeTo, int zorder);
+    private static native void nativeSetPosition(long transactionObj, long nativeObject,
+            float x, float y);
+    private static native void nativeSetGeometryAppliesWithResize(long transactionObj,
+            long nativeObject);
+    private static native void nativeSetSize(long transactionObj, long nativeObject, int w, int h);
+    private static native void nativeSetTransparentRegionHint(long transactionObj,
+            long nativeObject, Region region);
+    private static native void nativeSetAlpha(long transactionObj, long nativeObject, float alpha);
+    private static native void nativeSetMatrix(long transactionObj, long nativeObject,
+            float dsdx, float dtdx,
             float dtdy, float dsdy);
-    private static native void nativeSetFlags(long nativeObject, int flags, int mask);
-    private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
-    private static native void nativeSetFinalCrop(long nativeObject, int l, int t, int r, int b);
-    private static native void nativeSetLayerStack(long nativeObject, int layerStack);
+    private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color);
+    private static native void nativeSetFlags(long transactionObj, long nativeObject,
+            int flags, int mask);
+    private static native void nativeSetWindowCrop(long transactionObj, long nativeObject,
+            int l, int t, int r, int b);
+    private static native void nativeSetFinalCrop(long transactionObj, long nativeObject,
+            int l, int t, int r, int b);
+    private static native void nativeSetLayerStack(long transactionObj, long nativeObject,
+            int layerStack);
 
     private static native boolean nativeClearContentFrameStats(long nativeObject);
     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
@@ -82,15 +98,16 @@
     private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
     private static native IBinder nativeCreateDisplay(String name, boolean secure);
     private static native void nativeDestroyDisplay(IBinder displayToken);
-    private static native void nativeSetDisplaySurface(
+    private static native void nativeSetDisplaySurface(long transactionObj,
             IBinder displayToken, long nativeSurfaceObject);
-    private static native void nativeSetDisplayLayerStack(
+    private static native void nativeSetDisplayLayerStack(long transactionObj,
             IBinder displayToken, int layerStack);
-    private static native void nativeSetDisplayProjection(
+    private static native void nativeSetDisplayProjection(long transactionObj,
             IBinder displayToken, int orientation,
             int l, int t, int r, int b,
             int L, int T, int R, int B);
-    private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height);
+    private static native void nativeSetDisplaySize(long transactionObj, IBinder displayToken,
+            int width, int height);
     private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
             IBinder displayToken);
     private static native int nativeGetActiveConfig(IBinder displayToken);
@@ -101,16 +118,17 @@
             int colorMode);
     private static native void nativeSetDisplayPowerMode(
             IBinder displayToken, int mode);
-    private static native void nativeDeferTransactionUntil(long nativeObject,
+    private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject,
             IBinder handle, long frame);
-    private static native void nativeDeferTransactionUntilSurface(long nativeObject,
+    private static native void nativeDeferTransactionUntilSurface(long transactionObj,
+            long nativeObject,
             long surfaceObject, long frame);
-    private static native void nativeReparentChildren(long nativeObject,
+    private static native void nativeReparentChildren(long transactionObj, long nativeObject,
             IBinder handle);
-    private static native void nativeReparent(long nativeObject,
+    private static native void nativeReparent(long transactionObj, long nativeObject,
             IBinder parentHandle);
-    private static native void nativeSeverChildren(long nativeObject);
-    private static native void nativeSetOverrideScalingMode(long nativeObject,
+    private static native void nativeSeverChildren(long transactionObj, long nativeObject);
+    private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject,
             int scalingMode);
     private static native IBinder nativeGetHandle(long nativeObject);
     private static native boolean nativeGetTransformToDisplayInverse(long nativeObject);
@@ -122,6 +140,9 @@
     private final String mName;
     long mNativeObject; // package visibility only for Surface.java access
 
+    static Transaction sGlobalTransaction;
+    static long sTransactionNestCount = 0;
+
     /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
 
     /**
@@ -377,11 +398,6 @@
         }
     }
 
-    @Override
-    public String toString() {
-        return "Surface(name=" + mName + ")";
-    }
-
     /**
      * Release the local reference to the server-side surface.
      * Always call release() when you're done with a Surface.
@@ -429,102 +445,141 @@
 
     /** start a transaction */
     public static void openTransaction() {
-        nativeOpenTransaction();
+        synchronized (SurfaceControl.class) {
+            if (sGlobalTransaction == null) {
+                sGlobalTransaction = new Transaction();
+            }
+            synchronized(SurfaceControl.class) {
+                sTransactionNestCount++;
+            }
+        }
+    }
+
+    private static void closeTransaction(boolean sync) {
+        synchronized(SurfaceControl.class) {
+            if (sTransactionNestCount == 0) {
+                Log.e(TAG, "Call to SurfaceControl.closeTransaction without matching openTransaction");
+            } else if (--sTransactionNestCount > 0) {
+                return;
+            }
+            sGlobalTransaction.apply(sync);
+        }
     }
 
     /** end a transaction */
     public static void closeTransaction() {
-        nativeCloseTransaction(false);
+        closeTransaction(false);
     }
 
     public static void closeTransactionSync() {
-        nativeCloseTransaction(true);
+        closeTransaction(true);
     }
 
     public void deferTransactionUntil(IBinder handle, long frame) {
         if (frame > 0) {
-            nativeDeferTransactionUntil(mNativeObject, handle, frame);
+            synchronized(SurfaceControl.class) {
+                sGlobalTransaction.deferTransactionUntil(this, handle, frame);
+            }
         }
     }
 
     public void deferTransactionUntil(Surface barrier, long frame) {
         if (frame > 0) {
-            nativeDeferTransactionUntilSurface(mNativeObject, barrier.mNativeObject, frame);
+            synchronized(SurfaceControl.class) {
+                sGlobalTransaction.deferTransactionUntilSurface(this, barrier, frame);
+            }
         }
     }
 
     public void reparentChildren(IBinder newParentHandle) {
-        nativeReparentChildren(mNativeObject, newParentHandle);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.reparentChildren(this, newParentHandle);
+        }
     }
 
-    /** Re-parents this layer to a new parent. */
     public void reparent(IBinder newParentHandle) {
-        nativeReparent(mNativeObject, newParentHandle);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.reparent(this, newParentHandle);
+        }
     }
 
     public void detachChildren() {
-        nativeSeverChildren(mNativeObject);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.detachChildren(this);
+        }
     }
 
     public void setOverrideScalingMode(int scalingMode) {
         checkNotReleased();
-        nativeSetOverrideScalingMode(mNativeObject, scalingMode);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setOverrideScalingMode(this, scalingMode);
+        }
     }
 
     public IBinder getHandle() {
         return nativeGetHandle(mNativeObject);
     }
 
-    /** flag the transaction as an animation */
     public static void setAnimationTransaction() {
-        nativeSetAnimationTransaction();
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setAnimationTransaction();
+        }
     }
 
     public void setLayer(int zorder) {
         checkNotReleased();
-        nativeSetLayer(mNativeObject, zorder);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setLayer(this, zorder);
+        }
     }
 
     public void setRelativeLayer(IBinder relativeTo, int zorder) {
         checkNotReleased();
-        nativeSetRelativeLayer(mNativeObject, relativeTo, zorder);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setRelativeLayer(this, relativeTo, zorder);
+        }
     }
 
     public void setPosition(float x, float y) {
         checkNotReleased();
-        nativeSetPosition(mNativeObject, x, y);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setPosition(this, x, y);
+        }
     }
 
-    /**
-     * If the buffer size changes in this transaction, position and crop updates specified
-     * in this transaction will not complete until a buffer of the new size
-     * arrives. As transform matrix and size are already frozen in this fashion,
-     * this enables totally freezing the surface until the resize has completed
-     * (at which point the geometry influencing aspects of this transaction will then occur)
-     */
     public void setGeometryAppliesWithResize() {
         checkNotReleased();
-        nativeSetGeometryAppliesWithResize(mNativeObject);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setGeometryAppliesWithResize(this);
+        }
     }
 
     public void setSize(int w, int h) {
         checkNotReleased();
-        nativeSetSize(mNativeObject, w, h);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setSize(this, w, h);
+        }
     }
 
     public void hide() {
         checkNotReleased();
-        nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.hide(this);
+        }
     }
 
     public void show() {
         checkNotReleased();
-        nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.show(this);
+        }
     }
 
     public void setTransparentRegionHint(Region region) {
         checkNotReleased();
-        nativeSetTransparentRegionHint(mNativeObject, region);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setTransparentRegionHint(this, region);
+        }
     }
 
     public boolean clearContentFrameStats() {
@@ -545,80 +600,70 @@
         return nativeGetAnimationFrameStats(outStats);
     }
 
-    /**
-     * Sets an alpha value for the entire Surface.  This value is combined with the
-     * per-pixel alpha.  It may be used with opaque Surfaces.
-     */
     public void setAlpha(float alpha) {
         checkNotReleased();
-        nativeSetAlpha(mNativeObject, alpha);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setAlpha(this, alpha);
+        }
     }
 
-    /**
-     * Sets a color for the Surface.
-     * @param color A float array with three values to represent r, g, b in range [0..1]
-     */
     public void setColor(@Size(3) float[] color) {
         checkNotReleased();
-        nativeSetColor(mNativeObject, color);
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setColor(this, color);
+        }
     }
 
     public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
         checkNotReleased();
-        nativeSetMatrix(mNativeObject, dsdx, dtdx, dtdy, dsdy);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setMatrix(this, dsdx, dtdx, dtdy, dsdy);
+        }
     }
 
     public void setWindowCrop(Rect crop) {
         checkNotReleased();
-        if (crop != null) {
-            nativeSetWindowCrop(mNativeObject,
-                crop.left, crop.top, crop.right, crop.bottom);
-        } else {
-            nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0);
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setWindowCrop(this, crop);
         }
     }
 
     public void setFinalCrop(Rect crop) {
         checkNotReleased();
-        if (crop != null) {
-            nativeSetFinalCrop(mNativeObject,
-                crop.left, crop.top, crop.right, crop.bottom);
-        } else {
-            nativeSetFinalCrop(mNativeObject, 0, 0, 0, 0);
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setFinalCrop(this, crop);
         }
     }
 
     public void setLayerStack(int layerStack) {
         checkNotReleased();
-        nativeSetLayerStack(mNativeObject, layerStack);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setLayerStack(this, layerStack);
+        }
     }
 
-    /**
-     * Sets the opacity of the surface.  Setting the flag is equivalent to creating the
-     * Surface with the {@link #OPAQUE} flag.
-     */
     public void setOpaque(boolean isOpaque) {
         checkNotReleased();
-        if (isOpaque) {
-            nativeSetFlags(mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE);
-        } else {
-            nativeSetFlags(mNativeObject, 0, SURFACE_OPAQUE);
+
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setOpaque(this, isOpaque);
         }
     }
 
-    /**
-     * Sets the security of the surface.  Setting the flag is equivalent to creating the
-     * Surface with the {@link #SECURE} flag.
-     */
     public void setSecure(boolean isSecure) {
         checkNotReleased();
-        if (isSecure) {
-            nativeSetFlags(mNativeObject, SECURE, SECURE);
-        } else {
-            nativeSetFlags(mNativeObject, 0, SECURE);
+
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setSecure(this, isSecure);
         }
     }
 
+    @Override
+    public String toString() {
+        return "Surface(name=" + mName + ")/@0x" +
+                Integer.toHexString(System.identityHashCode(this));
+    }
+
     /*
      * set display parameters.
      * needs to be inside open/closeTransaction block
@@ -741,50 +786,28 @@
 
     public static void setDisplayProjection(IBinder displayToken,
             int orientation, Rect layerStackRect, Rect displayRect) {
-        if (displayToken == null) {
-            throw new IllegalArgumentException("displayToken must not be null");
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setDisplayProjection(displayToken, orientation,
+                    layerStackRect, displayRect);
         }
-        if (layerStackRect == null) {
-            throw new IllegalArgumentException("layerStackRect must not be null");
-        }
-        if (displayRect == null) {
-            throw new IllegalArgumentException("displayRect must not be null");
-        }
-        nativeSetDisplayProjection(displayToken, orientation,
-                layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
-                displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
     }
 
     public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
-        if (displayToken == null) {
-            throw new IllegalArgumentException("displayToken must not be null");
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setDisplayLayerStack(displayToken, layerStack);
         }
-        nativeSetDisplayLayerStack(displayToken, layerStack);
     }
 
     public static void setDisplaySurface(IBinder displayToken, Surface surface) {
-        if (displayToken == null) {
-            throw new IllegalArgumentException("displayToken must not be null");
-        }
-
-        if (surface != null) {
-            synchronized (surface.mLock) {
-                nativeSetDisplaySurface(displayToken, surface.mNativeObject);
-            }
-        } else {
-            nativeSetDisplaySurface(displayToken, 0);
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setDisplaySurface(displayToken, surface);
         }
     }
 
     public static void setDisplaySize(IBinder displayToken, int width, int height) {
-        if (displayToken == null) {
-            throw new IllegalArgumentException("displayToken must not be null");
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setDisplaySize(displayToken, width, height);
         }
-        if (width <= 0 || height <= 0) {
-            throw new IllegalArgumentException("width and height must be positive");
-        }
-
-        nativeSetDisplaySize(displayToken, width, height);
     }
 
     public static Display.HdrCapabilities getHdrCapabilities(IBinder displayToken) {
@@ -946,4 +969,261 @@
         nativeScreenshot(display, consumer, sourceCrop, width, height,
                 minLayer, maxLayer, allLayers, useIdentityTransform);
     }
+
+    public static class Transaction implements Closeable {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                Transaction.class.getClassLoader(),
+                nativeGetNativeTransactionFinalizer(), 512);
+        private long mNativeObject;
+
+        Runnable mFreeNativeResources;
+
+        public Transaction() {
+            mNativeObject = nativeCreateTransaction();
+            mFreeNativeResources
+                = sRegistry.registerNativeAllocation(this, mNativeObject);
+        }
+
+        /**
+         * Apply the transaction, clearing it's state, and making it usable
+         * as a new transaction.
+         */
+        public void apply() {
+            apply(false);
+        }
+
+        /**
+         * Close the transaction, if the transaction was not already applied this will cancel the
+         * transaction.
+         */
+        @Override
+        public void close() {
+            mFreeNativeResources.run();
+            mNativeObject = 0;
+        }
+
+        /**
+         * Jankier version of apply. Avoid use (b/28068298).
+         */
+        public void apply(boolean sync) {
+            nativeApplyTransaction(mNativeObject, sync);
+        }
+
+        public Transaction show(SurfaceControl sc) {
+            nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN);
+            return this;
+        }
+
+        public Transaction hide(SurfaceControl sc) {
+            nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
+            return this;
+        }
+
+        public Transaction setPosition(SurfaceControl sc, float x, float y) {
+            nativeSetPosition(mNativeObject, sc.mNativeObject, x, y);
+            return this;
+        }
+
+        public Transaction setSize(SurfaceControl sc, int w, int h) {
+            nativeSetSize(mNativeObject, sc.mNativeObject,
+                    w, h);
+            return this;
+        }
+
+        public Transaction setLayer(SurfaceControl sc, int z) {
+            nativeSetLayer(mNativeObject, sc.mNativeObject, z);
+            return this;
+        }
+
+        public Transaction setRelativeLayer(SurfaceControl sc, IBinder relativeTo, int z) {
+            nativeSetRelativeLayer(mNativeObject, sc.mNativeObject,
+                    relativeTo, z);
+            return this;
+        }
+
+        public Transaction setTransparentRegionHint(SurfaceControl sc, Region transparentRegion) {
+            nativeSetTransparentRegionHint(mNativeObject,
+                    sc.mNativeObject, transparentRegion);
+            return this;
+        }
+
+        public Transaction setAlpha(SurfaceControl sc, float alpha) {
+            nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha);
+            return this;
+        }
+
+        public Transaction setMatrix(SurfaceControl sc,
+                float dsdx, float dtdx, float dtdy, float dsdy) {
+            nativeSetMatrix(mNativeObject, sc.mNativeObject,
+                    dsdx, dtdx, dtdy, dsdy);
+            return this;
+        }
+
+        public Transaction setWindowCrop(SurfaceControl sc, Rect crop) {
+            if (crop != null) {
+                nativeSetWindowCrop(mNativeObject, sc.mNativeObject,
+                        crop.left, crop.top, crop.right, crop.bottom);
+            } else {
+                nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0);
+            }
+
+            return this;
+        }
+
+        public Transaction setFinalCrop(SurfaceControl sc, Rect crop) {
+            if (crop != null) {
+                nativeSetFinalCrop(mNativeObject, sc.mNativeObject,
+                        crop.left, crop.top, crop.right, crop.bottom);
+            } else {
+                nativeSetFinalCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0);
+            }
+
+            return this;
+        }
+
+        public Transaction setLayerStack(SurfaceControl sc, int layerStack) {
+            nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack);
+            return this;
+        }
+
+        public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle, long frameNumber) {
+            nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, handle, frameNumber);
+            return this;
+        }
+
+        public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface,
+                long frameNumber) {
+            nativeDeferTransactionUntilSurface(mNativeObject, sc.mNativeObject,
+                    barrierSurface.mNativeObject, frameNumber);
+            return this;
+        }
+
+        public Transaction reparentChildren(SurfaceControl sc, IBinder newParentHandle) {
+            nativeReparentChildren(mNativeObject, sc.mNativeObject, newParentHandle);
+            return this;
+        }
+
+        /** Re-parents a specific child layer to a new parent */
+        public Transaction reparent(SurfaceControl sc, IBinder newParentHandle) {
+            nativeReparent(mNativeObject, sc.mNativeObject,
+                    newParentHandle);
+            return this;
+        }
+
+        public Transaction detachChildren(SurfaceControl sc) {
+            nativeSeverChildren(mNativeObject, sc.mNativeObject);
+            return this;
+        }
+
+        public Transaction setOverrideScalingMode(SurfaceControl sc, int overrideScalingMode) {
+            nativeSetOverrideScalingMode(mNativeObject, sc.mNativeObject,
+                    overrideScalingMode);
+            return this;
+        }
+
+        /**
+         * Sets a color for the Surface.
+         * @param color A float array with three values to represent r, g, b in range [0..1]
+         */
+        public Transaction setColor(SurfaceControl sc, @Size(3) float[] color) {
+            nativeSetColor(mNativeObject, sc.mNativeObject, color);
+            return this;
+        }
+
+        /**
+         * If the buffer size changes in this transaction, position and crop updates specified
+         * in this transaction will not complete until a buffer of the new size
+         * arrives. As transform matrix and size are already frozen in this fashion,
+         * this enables totally freezing the surface until the resize has completed
+         * (at which point the geometry influencing aspects of this transaction will then occur)
+         */
+        public Transaction setGeometryAppliesWithResize(SurfaceControl sc) {
+            nativeSetGeometryAppliesWithResize(mNativeObject, sc.mNativeObject);
+            return this;
+        }
+
+        /**
+         * Sets the security of the surface.  Setting the flag is equivalent to creating the
+         * Surface with the {@link #SECURE} flag.
+         */
+        Transaction setSecure(SurfaceControl sc, boolean isSecure) {
+            if (isSecure) {
+                nativeSetFlags(mNativeObject, sc.mNativeObject, SECURE, SECURE);
+            } else {
+                nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SECURE);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the opacity of the surface.  Setting the flag is equivalent to creating the
+         * Surface with the {@link #OPAQUE} flag.
+         */
+        public Transaction setOpaque(SurfaceControl sc, boolean isOpaque) {
+            if (isOpaque) {
+                nativeSetFlags(mNativeObject, sc.mNativeObject, OPAQUE, OPAQUE);
+            } else {
+                nativeSetFlags(mNativeObject, sc.mNativeObject, 0, OPAQUE);
+            }
+            return this;
+        }
+
+        public Transaction setDisplaySurface(IBinder displayToken, Surface surface) {
+            if (displayToken == null) {
+                throw new IllegalArgumentException("displayToken must not be null");
+            }
+
+            if (surface != null) {
+                synchronized (surface.mLock) {
+                    nativeSetDisplaySurface(mNativeObject, displayToken, surface.mNativeObject);
+                }
+            } else {
+                nativeSetDisplaySurface(mNativeObject, displayToken, 0);
+            }
+            return this;
+        }
+
+        public Transaction setDisplayLayerStack(IBinder displayToken, int layerStack) {
+            if (displayToken == null) {
+                throw new IllegalArgumentException("displayToken must not be null");
+            }
+            nativeSetDisplayLayerStack(mNativeObject, displayToken, layerStack);
+            return this;
+        }
+
+        public Transaction setDisplayProjection(IBinder displayToken,
+                int orientation, Rect layerStackRect, Rect displayRect) {
+            if (displayToken == null) {
+                throw new IllegalArgumentException("displayToken must not be null");
+            }
+            if (layerStackRect == null) {
+                throw new IllegalArgumentException("layerStackRect must not be null");
+            }
+            if (displayRect == null) {
+                throw new IllegalArgumentException("displayRect must not be null");
+            }
+            nativeSetDisplayProjection(mNativeObject, displayToken, orientation,
+                    layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
+                    displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
+            return this;
+        }
+
+        public Transaction setDisplaySize(IBinder displayToken, int width, int height) {
+            if (displayToken == null) {
+                throw new IllegalArgumentException("displayToken must not be null");
+            }
+            if (width <= 0 || height <= 0) {
+                throw new IllegalArgumentException("width and height must be positive");
+            }
+
+            nativeSetDisplaySize(mNativeObject, displayToken, width, height);
+            return this;
+        }
+
+        /** flag the transaction as an animation */
+        public Transaction setAnimationTransaction() {
+            nativeSetAnimationTransaction(mNativeObject);
+            return this;
+        }
+    }
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b6be296..c043dca 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1448,17 +1448,59 @@
 
     /**
      * <p>Enables low quality mode for the drawing cache.</p>
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public static final int DRAWING_CACHE_QUALITY_LOW = 0x00080000;
 
     /**
      * <p>Enables high quality mode for the drawing cache.</p>
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public static final int DRAWING_CACHE_QUALITY_HIGH = 0x00100000;
 
     /**
      * <p>Enables automatic quality mode for the drawing cache.</p>
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public static final int DRAWING_CACHE_QUALITY_AUTO = 0x00000000;
 
     private static final int[] DRAWING_CACHE_QUALITY_FLAGS = {
@@ -2300,9 +2342,9 @@
     private static final int PFLAG_HOVERED             = 0x10000000;
 
     /**
-     * no longer needed, should be reused
+     * Flag set by {@link AutofillManager} if it needs to be notified when this view is clicked.
      */
-    private static final int PFLAG_DOES_NOTHING_REUSE_PLEASE = 0x20000000;
+    private static final int PFLAG_NOTIFY_AUTOFILL_MANAGER_ON_CLICK = 0x20000000;
 
     /** {@hide} */
     static final int PFLAG_ACTIVATED                   = 0x40000000;
@@ -6355,6 +6397,42 @@
         return null;
     }
 
+    /** @hide */
+    public void setNotifyAutofillManagerOnClick(boolean notify) {
+        if (notify) {
+            mPrivateFlags |= PFLAG_NOTIFY_AUTOFILL_MANAGER_ON_CLICK;
+        } else {
+            mPrivateFlags &= ~PFLAG_NOTIFY_AUTOFILL_MANAGER_ON_CLICK;
+        }
+    }
+
+    private void notifyAutofillManagerOnClick() {
+        if ((mPrivateFlags & PFLAG_NOTIFY_AUTOFILL_MANAGER_ON_CLICK) != 0) {
+            try {
+                getAutofillManager().notifyViewClicked(this);
+            } finally {
+                // Set it to already called so it's not called twice when called by
+                // performClickInternal()
+                mPrivateFlags |= ~PFLAG_NOTIFY_AUTOFILL_MANAGER_ON_CLICK;
+            }
+        }
+    }
+
+    /**
+     * Entry point for {@link #performClick()} - other methods on View should call it instead of
+     * {@code performClick()} directly to make sure the autofill manager is notified when
+     * necessary (as subclasses could extend {@code performClick()} without calling the parent's
+     * method).
+     */
+    private boolean performClickInternal() {
+        // Must notify autofill manager before performing the click actions to avoid scenarios where
+        // the app has a click listener that changes the state of views the autofill service might
+        // be interested on.
+        notifyAutofillManagerOnClick();
+
+        return performClick();
+    }
+
     /**
      * Call this view's OnClickListener, if it is defined.  Performs all normal
      * actions associated with clicking: reporting accessibility event, playing
@@ -6363,7 +6441,14 @@
      * @return True there was an assigned OnClickListener that was called, false
      *         otherwise is returned.
      */
+    // NOTE: other methods on View should not call this method directly, but performClickInternal()
+    // instead, to guarantee that the autofill manager is notified when necessary (as subclasses
+    // could extend this method without calling super.performClick()).
     public boolean performClick() {
+        // We still need to call this method to handle the cases where performClick() was called
+        // externally, instead of through performClickInternal()
+        notifyAutofillManagerOnClick();
+
         final boolean result;
         final ListenerInfo li = mListenerInfo;
         if (li != null && li.mOnClickListener != null) {
@@ -8907,7 +8992,21 @@
      * @see #isDrawingCacheEnabled()
      *
      * @attr ref android.R.styleable#View_drawingCacheQuality
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     @DrawingCacheQuality
     public int getDrawingCacheQuality() {
         return mViewFlags & DRAWING_CACHE_QUALITY_MASK;
@@ -8925,7 +9024,21 @@
      * @see #isDrawingCacheEnabled()
      *
      * @attr ref android.R.styleable#View_drawingCacheQuality
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public void setDrawingCacheQuality(@DrawingCacheQuality int quality) {
         setFlags(quality, DRAWING_CACHE_QUALITY_MASK);
     }
@@ -11433,7 +11546,7 @@
         switch (action) {
             case AccessibilityNodeInfo.ACTION_CLICK: {
                 if (isClickable()) {
-                    performClick();
+                    performClickInternal();
                     return true;
                 }
             } break;
@@ -12545,7 +12658,7 @@
                     // This is a tap, so remove the longpress check
                     removeLongPressCallback();
                     if (!event.isCanceled()) {
-                        return performClick();
+                        return performClickInternal();
                     }
                 }
             }
@@ -13117,7 +13230,7 @@
                                     mPerformClick = new PerformClick();
                                 }
                                 if (!post(mPerformClick)) {
-                                    performClick();
+                                    performClickInternal();
                                 }
                             }
                         }
@@ -18103,7 +18216,21 @@
      * @see #getDrawingCache()
      * @see #buildDrawingCache()
      * @see #setLayerType(int, android.graphics.Paint)
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public void setDrawingCacheEnabled(boolean enabled) {
         mCachingFailed = false;
         setFlags(enabled ? DRAWING_CACHE_ENABLED : 0, DRAWING_CACHE_ENABLED);
@@ -18116,7 +18243,21 @@
      *
      * @see #setDrawingCacheEnabled(boolean)
      * @see #getDrawingCache()
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     @ViewDebug.ExportedProperty(category = "drawing")
     public boolean isDrawingCacheEnabled() {
         return (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED;
@@ -18130,10 +18271,11 @@
      */
     @SuppressWarnings({"UnusedDeclaration"})
     public void outputDirtyFlags(String indent, boolean clear, int clearMask) {
-        Log.d("View", indent + this + "             DIRTY(" + (mPrivateFlags & View.PFLAG_DIRTY_MASK) +
-                ") DRAWN(" + (mPrivateFlags & PFLAG_DRAWN) + ")" + " CACHE_VALID(" +
-                (mPrivateFlags & View.PFLAG_DRAWING_CACHE_VALID) +
-                ") INVALIDATED(" + (mPrivateFlags & PFLAG_INVALIDATED) + ")");
+        Log.d(VIEW_LOG_TAG, indent + this + "             DIRTY("
+                + (mPrivateFlags & View.PFLAG_DIRTY_MASK)
+                + ") DRAWN(" + (mPrivateFlags & PFLAG_DRAWN) + ")" + " CACHE_VALID("
+                + (mPrivateFlags & View.PFLAG_DRAWING_CACHE_VALID)
+                + ") INVALIDATED(" + (mPrivateFlags & PFLAG_INVALIDATED) + ")");
         if (clear) {
             mPrivateFlags &= clearMask;
         }
@@ -18257,7 +18399,21 @@
      * @return A non-scaled bitmap representing this view or null if cache is disabled.
      *
      * @see #getDrawingCache(boolean)
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public Bitmap getDrawingCache() {
         return getDrawingCache(false);
     }
@@ -18288,7 +18444,21 @@
      * @see #isDrawingCacheEnabled()
      * @see #buildDrawingCache(boolean)
      * @see #destroyDrawingCache()
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public Bitmap getDrawingCache(boolean autoScale) {
         if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
             return null;
@@ -18308,7 +18478,21 @@
      * @see #setDrawingCacheEnabled(boolean)
      * @see #buildDrawingCache()
      * @see #getDrawingCache()
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public void destroyDrawingCache() {
         if (mDrawingCache != null) {
             mDrawingCache.recycle();
@@ -18330,7 +18514,21 @@
      * @see #setDrawingCacheEnabled(boolean)
      * @see #buildDrawingCache()
      * @see #getDrawingCache()
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public void setDrawingCacheBackgroundColor(@ColorInt int color) {
         if (color != mDrawingCacheBackgroundColor) {
             mDrawingCacheBackgroundColor = color;
@@ -18342,7 +18540,21 @@
      * @see #setDrawingCacheBackgroundColor(int)
      *
      * @return The background color to used for the drawing cache's bitmap
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     @ColorInt
     public int getDrawingCacheBackgroundColor() {
         return mDrawingCacheBackgroundColor;
@@ -18352,7 +18564,21 @@
      * <p>Calling this method is equivalent to calling <code>buildDrawingCache(false)</code>.</p>
      *
      * @see #buildDrawingCache(boolean)
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public void buildDrawingCache() {
         buildDrawingCache(false);
     }
@@ -18379,7 +18605,21 @@
      *
      * @see #getDrawingCache()
      * @see #destroyDrawingCache()
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public void buildDrawingCache(boolean autoScale) {
         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
                 mDrawingCache == null : mUnscaledDrawingCache == null)) {
@@ -19812,7 +20052,7 @@
         boolean changed = false;
 
         if (DBG) {
-            Log.d("View", this + " View.setFrame(" + left + "," + top + ","
+            Log.d(VIEW_LOG_TAG, this + " View.setFrame(" + left + "," + top + ","
                     + right + "," + bottom + ")");
         }
 
@@ -24858,7 +25098,7 @@
     private final class PerformClick implements Runnable {
         @Override
         public void run() {
-            performClick();
+            performClickInternal();
         }
     }
 
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b2e5a16..929beae 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -421,22 +421,78 @@
 
     /**
      * Used to indicate that no drawing cache should be kept in memory.
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public static final int PERSISTENT_NO_CACHE = 0x0;
 
     /**
      * Used to indicate that the animation drawing cache should be kept in memory.
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public static final int PERSISTENT_ANIMATION_CACHE = 0x1;
 
     /**
      * Used to indicate that the scrolling drawing cache should be kept in memory.
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public static final int PERSISTENT_SCROLLING_CACHE = 0x2;
 
     /**
      * Used to indicate that all drawing caches should be kept in memory.
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public static final int PERSISTENT_ALL_CACHES = 0x3;
 
     // Layout Modes
@@ -3769,7 +3825,21 @@
      * Enables or disables the drawing cache for each child of this view group.
      *
      * @param enabled true to enable the cache, false to dispose of it
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     protected void setChildrenDrawingCacheEnabled(boolean enabled) {
         if (enabled || (mPersistentDrawingCache & PERSISTENT_ALL_CACHES) != PERSISTENT_ALL_CACHES) {
             final View[] children = mChildren;
@@ -6331,7 +6401,21 @@
      * @return one or a combination of {@link #PERSISTENT_NO_CACHE},
      *         {@link #PERSISTENT_ANIMATION_CACHE}, {@link #PERSISTENT_SCROLLING_CACHE}
      *         and {@link #PERSISTENT_ALL_CACHES}
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     @ViewDebug.ExportedProperty(category = "drawing", mapping = {
         @ViewDebug.IntToString(from = PERSISTENT_NO_CACHE,        to = "NONE"),
         @ViewDebug.IntToString(from = PERSISTENT_ANIMATION_CACHE, to = "ANIMATION"),
@@ -6352,7 +6436,21 @@
      * @param drawingCacheToKeep one or a combination of {@link #PERSISTENT_NO_CACHE},
      *        {@link #PERSISTENT_ANIMATION_CACHE}, {@link #PERSISTENT_SCROLLING_CACHE}
      *        and {@link #PERSISTENT_ALL_CACHES}
+     *
+     * @deprecated The view drawing cache was largely made obsolete with the introduction of
+     * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache
+     * layers are largely unnecessary and can easily result in a net loss in performance due to the
+     * cost of creating and updating the layer. In the rare cases where caching layers are useful,
+     * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware
+     * rendering. For software-rendered snapshots of a small part of the View hierarchy or
+     * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or
+     * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these
+     * software-rendered usages are discouraged and have compatibility issues with hardware-only
+     * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE}
+     * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback
+     * reports or unit testing the {@link PixelCopy} API is recommended.
      */
+    @Deprecated
     public void setPersistentDrawingCache(int drawingCacheToKeep) {
         mPersistentDrawingCache = drawingCacheToKeep & PERSISTENT_ALL_CACHES;
     }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 71106ad..99438d8 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -72,6 +72,7 @@
 import android.util.Log;
 import android.util.MergedConfiguration;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.TimeUtils;
 import android.util.TypedValue;
 import android.view.Surface.OutOfResourcesException;
@@ -1668,8 +1669,6 @@
             host.dispatchAttachedToWindow(mAttachInfo, 0);
             mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
             dispatchApplyInsets(host);
-            //Log.i(mTag, "Screen on initialized: " + attachInfo.mKeepScreenOn);
-
         } else {
             desiredWindowWidth = frame.width();
             desiredWindowHeight = frame.height();
@@ -2827,7 +2826,7 @@
                 try {
                     mWindowDrawCountDown.await();
                 } catch (InterruptedException e) {
-                    Log.e(mTag, "Window redraw count down interruped!");
+                    Log.e(mTag, "Window redraw count down interrupted!");
                 }
                 mWindowDrawCountDown = null;
             }
@@ -2897,8 +2896,6 @@
         final float appScale = mAttachInfo.mApplicationScale;
         final boolean scalingRequired = mAttachInfo.mScalingRequired;
 
-        int resizeAlpha = 0;
-
         final Rect dirty = mDirty;
         if (mSurfaceHolder != null) {
             // The app owns the surface, we won't draw.
@@ -3469,6 +3466,7 @@
     }
 
     void dispatchDetachedFromWindow() {
+        mFirstInputStage.onDetachedFromWindow();
         if (mView != null && mView.mAttachInfo != null) {
             mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(false);
             mView.dispatchDetachedFromWindow();
@@ -3731,266 +3729,273 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-            case MSG_INVALIDATE:
-                ((View) msg.obj).invalidate();
-                break;
-            case MSG_INVALIDATE_RECT:
-                final View.AttachInfo.InvalidateInfo info = (View.AttachInfo.InvalidateInfo) msg.obj;
-                info.target.invalidate(info.left, info.top, info.right, info.bottom);
-                info.recycle();
-                break;
-            case MSG_PROCESS_INPUT_EVENTS:
-                mProcessInputEventsScheduled = false;
-                doProcessInputEvents();
-                break;
-            case MSG_DISPATCH_APP_VISIBILITY:
-                handleAppVisibility(msg.arg1 != 0);
-                break;
-            case MSG_DISPATCH_GET_NEW_SURFACE:
-                handleGetNewSurface();
-                break;
-            case MSG_RESIZED: {
-                // Recycled in the fall through...
-                SomeArgs args = (SomeArgs) msg.obj;
-                if (mWinFrame.equals(args.arg1)
-                        && mPendingOverscanInsets.equals(args.arg5)
-                        && mPendingContentInsets.equals(args.arg2)
-                        && mPendingStableInsets.equals(args.arg6)
-                        && mPendingVisibleInsets.equals(args.arg3)
-                        && mPendingOutsets.equals(args.arg7)
-                        && mPendingBackDropFrame.equals(args.arg8)
-                        && args.arg4 == null
-                        && args.argi1 == 0
-                        && mDisplay.getDisplayId() == args.argi3) {
+                case MSG_INVALIDATE:
+                    ((View) msg.obj).invalidate();
                     break;
-                }
-                } // fall through...
-            case MSG_RESIZED_REPORT:
-                if (mAdded) {
+                case MSG_INVALIDATE_RECT:
+                    final View.AttachInfo.InvalidateInfo info =
+                            (View.AttachInfo.InvalidateInfo) msg.obj;
+                    info.target.invalidate(info.left, info.top, info.right, info.bottom);
+                    info.recycle();
+                    break;
+                case MSG_PROCESS_INPUT_EVENTS:
+                    mProcessInputEventsScheduled = false;
+                    doProcessInputEvents();
+                    break;
+                case MSG_DISPATCH_APP_VISIBILITY:
+                    handleAppVisibility(msg.arg1 != 0);
+                    break;
+                case MSG_DISPATCH_GET_NEW_SURFACE:
+                    handleGetNewSurface();
+                    break;
+                case MSG_RESIZED: {
+                    // Recycled in the fall through...
                     SomeArgs args = (SomeArgs) msg.obj;
-
-                    final int displayId = args.argi3;
-                    MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
-                    final boolean displayChanged = mDisplay.getDisplayId() != displayId;
-
-                    if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) {
-                        // If configuration changed - notify about that and, maybe, about move to
-                        // display.
-                        performConfigurationChange(mergedConfiguration, false /* force */,
-                                displayChanged ? displayId : INVALID_DISPLAY /* same display */);
-                    } else if (displayChanged) {
-                        // Moved to display without config change - report last applied one.
-                        onMovedToDisplay(displayId, mLastConfigurationFromResources);
+                    if (mWinFrame.equals(args.arg1)
+                            && mPendingOverscanInsets.equals(args.arg5)
+                            && mPendingContentInsets.equals(args.arg2)
+                            && mPendingStableInsets.equals(args.arg6)
+                            && mPendingVisibleInsets.equals(args.arg3)
+                            && mPendingOutsets.equals(args.arg7)
+                            && mPendingBackDropFrame.equals(args.arg8)
+                            && args.arg4 == null
+                            && args.argi1 == 0
+                            && mDisplay.getDisplayId() == args.argi3) {
+                        break;
                     }
+                } // fall through...
+                case MSG_RESIZED_REPORT:
+                    if (mAdded) {
+                        SomeArgs args = (SomeArgs) msg.obj;
 
-                    final boolean framesChanged = !mWinFrame.equals(args.arg1)
-                            || !mPendingOverscanInsets.equals(args.arg5)
-                            || !mPendingContentInsets.equals(args.arg2)
-                            || !mPendingStableInsets.equals(args.arg6)
-                            || !mPendingVisibleInsets.equals(args.arg3)
-                            || !mPendingOutsets.equals(args.arg7);
+                        final int displayId = args.argi3;
+                        MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
+                        final boolean displayChanged = mDisplay.getDisplayId() != displayId;
 
-                    mWinFrame.set((Rect) args.arg1);
-                    mPendingOverscanInsets.set((Rect) args.arg5);
-                    mPendingContentInsets.set((Rect) args.arg2);
-                    mPendingStableInsets.set((Rect) args.arg6);
-                    mPendingVisibleInsets.set((Rect) args.arg3);
-                    mPendingOutsets.set((Rect) args.arg7);
-                    mPendingBackDropFrame.set((Rect) args.arg8);
-                    mForceNextWindowRelayout = args.argi1 != 0;
-                    mPendingAlwaysConsumeNavBar = args.argi2 != 0;
+                        if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) {
+                            // If configuration changed - notify about that and, maybe,
+                            // about move to display.
+                            performConfigurationChange(mergedConfiguration, false /* force */,
+                                    displayChanged
+                                            ? displayId : INVALID_DISPLAY /* same display */);
+                        } else if (displayChanged) {
+                            // Moved to display without config change - report last applied one.
+                            onMovedToDisplay(displayId, mLastConfigurationFromResources);
+                        }
 
-                    args.recycle();
+                        final boolean framesChanged = !mWinFrame.equals(args.arg1)
+                                || !mPendingOverscanInsets.equals(args.arg5)
+                                || !mPendingContentInsets.equals(args.arg2)
+                                || !mPendingStableInsets.equals(args.arg6)
+                                || !mPendingVisibleInsets.equals(args.arg3)
+                                || !mPendingOutsets.equals(args.arg7);
 
-                    if (msg.what == MSG_RESIZED_REPORT) {
-                        reportNextDraw();
+                        mWinFrame.set((Rect) args.arg1);
+                        mPendingOverscanInsets.set((Rect) args.arg5);
+                        mPendingContentInsets.set((Rect) args.arg2);
+                        mPendingStableInsets.set((Rect) args.arg6);
+                        mPendingVisibleInsets.set((Rect) args.arg3);
+                        mPendingOutsets.set((Rect) args.arg7);
+                        mPendingBackDropFrame.set((Rect) args.arg8);
+                        mForceNextWindowRelayout = args.argi1 != 0;
+                        mPendingAlwaysConsumeNavBar = args.argi2 != 0;
+
+                        args.recycle();
+
+                        if (msg.what == MSG_RESIZED_REPORT) {
+                            reportNextDraw();
+                        }
+
+                        if (mView != null && framesChanged) {
+                            forceLayout(mView);
+                        }
+                        requestLayout();
                     }
+                    break;
+                case MSG_WINDOW_MOVED:
+                    if (mAdded) {
+                        final int w = mWinFrame.width();
+                        final int h = mWinFrame.height();
+                        final int l = msg.arg1;
+                        final int t = msg.arg2;
+                        mWinFrame.left = l;
+                        mWinFrame.right = l + w;
+                        mWinFrame.top = t;
+                        mWinFrame.bottom = t + h;
 
-                    if (mView != null && framesChanged) {
-                        forceLayout(mView);
+                        mPendingBackDropFrame.set(mWinFrame);
+                        maybeHandleWindowMove(mWinFrame);
                     }
-                    requestLayout();
-                }
-                break;
-            case MSG_WINDOW_MOVED:
-                if (mAdded) {
-                    final int w = mWinFrame.width();
-                    final int h = mWinFrame.height();
-                    final int l = msg.arg1;
-                    final int t = msg.arg2;
-                    mWinFrame.left = l;
-                    mWinFrame.right = l + w;
-                    mWinFrame.top = t;
-                    mWinFrame.bottom = t + h;
+                    break;
+                case MSG_WINDOW_FOCUS_CHANGED: {
+                    final boolean hasWindowFocus = msg.arg1 != 0;
+                    if (mAdded) {
+                        mAttachInfo.mHasWindowFocus = hasWindowFocus;
 
-                    mPendingBackDropFrame.set(mWinFrame);
-                    maybeHandleWindowMove(mWinFrame);
-                }
-                break;
-            case MSG_WINDOW_FOCUS_CHANGED: {
-                if (mAdded) {
-                    boolean hasWindowFocus = msg.arg1 != 0;
-                    mAttachInfo.mHasWindowFocus = hasWindowFocus;
+                        profileRendering(hasWindowFocus);
 
-                    profileRendering(hasWindowFocus);
-
-                    if (hasWindowFocus) {
-                        boolean inTouchMode = msg.arg2 != 0;
-                        ensureTouchModeLocally(inTouchMode);
-
-                        if (mAttachInfo.mThreadedRenderer != null && mSurface.isValid()){
-                            mFullRedrawNeeded = true;
-                            try {
-                                final WindowManager.LayoutParams lp = mWindowAttributes;
-                                final Rect surfaceInsets = lp != null ? lp.surfaceInsets : null;
-                                mAttachInfo.mThreadedRenderer.initializeIfNeeded(
-                                        mWidth, mHeight, mAttachInfo, mSurface, surfaceInsets);
-                            } catch (OutOfResourcesException e) {
-                                Log.e(mTag, "OutOfResourcesException locking surface", e);
+                        if (hasWindowFocus) {
+                            boolean inTouchMode = msg.arg2 != 0;
+                            ensureTouchModeLocally(inTouchMode);
+                            if (mAttachInfo.mThreadedRenderer != null && mSurface.isValid()) {
+                                mFullRedrawNeeded = true;
                                 try {
-                                    if (!mWindowSession.outOfMemory(mWindow)) {
-                                        Slog.w(mTag, "No processes killed for memory; killing self");
-                                        Process.killProcess(Process.myPid());
+                                    final WindowManager.LayoutParams lp = mWindowAttributes;
+                                    final Rect surfaceInsets = lp != null ? lp.surfaceInsets : null;
+                                    mAttachInfo.mThreadedRenderer.initializeIfNeeded(
+                                            mWidth, mHeight, mAttachInfo, mSurface, surfaceInsets);
+                                } catch (OutOfResourcesException e) {
+                                    Log.e(mTag, "OutOfResourcesException locking surface", e);
+                                    try {
+                                        if (!mWindowSession.outOfMemory(mWindow)) {
+                                            Slog.w(mTag, "No processes killed for memory;"
+                                                    + " killing self");
+                                            Process.killProcess(Process.myPid());
+                                        }
+                                    } catch (RemoteException ex) {
                                     }
-                                } catch (RemoteException ex) {
+                                    // Retry in a bit.
+                                    sendMessageDelayed(obtainMessage(msg.what, msg.arg1, msg.arg2),
+                                            500);
+                                    return;
                                 }
-                                // Retry in a bit.
-                                sendMessageDelayed(obtainMessage(msg.what, msg.arg1, msg.arg2), 500);
-                                return;
+                            }
+                        }
+
+                        mLastWasImTarget = WindowManager.LayoutParams
+                                .mayUseInputMethod(mWindowAttributes.flags);
+
+                        InputMethodManager imm = InputMethodManager.peekInstance();
+                        if (imm != null && mLastWasImTarget && !isInLocalFocusMode()) {
+                            imm.onPreWindowFocus(mView, hasWindowFocus);
+                        }
+                        if (mView != null) {
+                            mAttachInfo.mKeyDispatchState.reset();
+                            mView.dispatchWindowFocusChanged(hasWindowFocus);
+                            mAttachInfo.mTreeObserver.dispatchOnWindowFocusChange(hasWindowFocus);
+
+                            if (mAttachInfo.mTooltipHost != null) {
+                                mAttachInfo.mTooltipHost.hideTooltip();
+                            }
+                        }
+
+                        // Note: must be done after the focus change callbacks,
+                        // so all of the view state is set up correctly.
+                        if (hasWindowFocus) {
+                            if (imm != null && mLastWasImTarget && !isInLocalFocusMode()) {
+                                imm.onPostWindowFocus(mView, mView.findFocus(),
+                                        mWindowAttributes.softInputMode,
+                                        !mHasHadWindowFocus, mWindowAttributes.flags);
+                            }
+                            // Clear the forward bit.  We can just do this directly, since
+                            // the window manager doesn't care about it.
+                            mWindowAttributes.softInputMode &=
+                                    ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
+                            ((WindowManager.LayoutParams) mView.getLayoutParams())
+                                    .softInputMode &=
+                                        ~WindowManager.LayoutParams
+                                                .SOFT_INPUT_IS_FORWARD_NAVIGATION;
+                            mHasHadWindowFocus = true;
+                        } else {
+                            if (mPointerCapture) {
+                                handlePointerCaptureChanged(false);
                             }
                         }
                     }
-
-                    mLastWasImTarget = WindowManager.LayoutParams
-                            .mayUseInputMethod(mWindowAttributes.flags);
-
+                    mFirstInputStage.onWindowFocusChanged(hasWindowFocus);
+                } break;
+                case MSG_DIE:
+                    doDie();
+                    break;
+                case MSG_DISPATCH_INPUT_EVENT: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    InputEvent event = (InputEvent) args.arg1;
+                    InputEventReceiver receiver = (InputEventReceiver) args.arg2;
+                    enqueueInputEvent(event, receiver, 0, true);
+                    args.recycle();
+                } break;
+                case MSG_SYNTHESIZE_INPUT_EVENT: {
+                    InputEvent event = (InputEvent) msg.obj;
+                    enqueueInputEvent(event, null, QueuedInputEvent.FLAG_UNHANDLED, true);
+                } break;
+                case MSG_DISPATCH_KEY_FROM_IME: {
+                    if (LOCAL_LOGV) {
+                        Log.v(TAG, "Dispatching key " + msg.obj + " from IME to " + mView);
+                    }
+                    KeyEvent event = (KeyEvent) msg.obj;
+                    if ((event.getFlags() & KeyEvent.FLAG_FROM_SYSTEM) != 0) {
+                        // The IME is trying to say this event is from the
+                        // system!  Bad bad bad!
+                        //noinspection UnusedAssignment
+                        event = KeyEvent.changeFlags(event,
+                                event.getFlags() & ~KeyEvent.FLAG_FROM_SYSTEM);
+                    }
+                    enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
+                } break;
+                case MSG_CHECK_FOCUS: {
                     InputMethodManager imm = InputMethodManager.peekInstance();
-                    if (imm != null && mLastWasImTarget && !isInLocalFocusMode()) {
-                        imm.onPreWindowFocus(mView, hasWindowFocus);
+                    if (imm != null) {
+                        imm.checkFocus();
                     }
+                } break;
+                case MSG_CLOSE_SYSTEM_DIALOGS: {
                     if (mView != null) {
-                        mAttachInfo.mKeyDispatchState.reset();
-                        mView.dispatchWindowFocusChanged(hasWindowFocus);
-                        mAttachInfo.mTreeObserver.dispatchOnWindowFocusChange(hasWindowFocus);
-
-                        if (mAttachInfo.mTooltipHost != null) {
-                            mAttachInfo.mTooltipHost.hideTooltip();
-                        }
+                        mView.onCloseSystemDialogs((String) msg.obj);
+                    }
+                } break;
+                case MSG_DISPATCH_DRAG_EVENT: {
+                } // fall through
+                case MSG_DISPATCH_DRAG_LOCATION_EVENT: {
+                    DragEvent event = (DragEvent) msg.obj;
+                    // only present when this app called startDrag()
+                    event.mLocalState = mLocalDragState;
+                    handleDragEvent(event);
+                } break;
+                case MSG_DISPATCH_SYSTEM_UI_VISIBILITY: {
+                    handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo) msg.obj);
+                } break;
+                case MSG_UPDATE_CONFIGURATION: {
+                    Configuration config = (Configuration) msg.obj;
+                    if (config.isOtherSeqNewer(
+                            mLastReportedMergedConfiguration.getMergedConfiguration())) {
+                        // If we already have a newer merged config applied - use its global part.
+                        config = mLastReportedMergedConfiguration.getGlobalConfiguration();
                     }
 
-                    // Note: must be done after the focus change callbacks,
-                    // so all of the view state is set up correctly.
-                    if (hasWindowFocus) {
-                        if (imm != null && mLastWasImTarget && !isInLocalFocusMode()) {
-                            imm.onPostWindowFocus(mView, mView.findFocus(),
-                                    mWindowAttributes.softInputMode,
-                                    !mHasHadWindowFocus, mWindowAttributes.flags);
-                        }
-                        // Clear the forward bit.  We can just do this directly, since
-                        // the window manager doesn't care about it.
-                        mWindowAttributes.softInputMode &=
-                                ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
-                        ((WindowManager.LayoutParams)mView.getLayoutParams())
-                                .softInputMode &=
-                                    ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
-                        mHasHadWindowFocus = true;
-                    } else {
-                        if (mPointerCapture) {
-                            handlePointerCaptureChanged(false);
-                        }
+                    // Use the newer global config and last reported override config.
+                    mPendingMergedConfiguration.setConfiguration(config,
+                            mLastReportedMergedConfiguration.getOverrideConfiguration());
+
+                    performConfigurationChange(mPendingMergedConfiguration, false /* force */,
+                            INVALID_DISPLAY /* same display */);
+                } break;
+                case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
+                    setAccessibilityFocus(null, null);
+                } break;
+                case MSG_INVALIDATE_WORLD: {
+                    if (mView != null) {
+                        invalidateWorld(mView);
                     }
-                }
-            } break;
-            case MSG_DIE:
-                doDie();
-                break;
-            case MSG_DISPATCH_INPUT_EVENT: {
-                SomeArgs args = (SomeArgs)msg.obj;
-                InputEvent event = (InputEvent)args.arg1;
-                InputEventReceiver receiver = (InputEventReceiver)args.arg2;
-                enqueueInputEvent(event, receiver, 0, true);
-                args.recycle();
-            } break;
-            case MSG_SYNTHESIZE_INPUT_EVENT: {
-                InputEvent event = (InputEvent)msg.obj;
-                enqueueInputEvent(event, null, QueuedInputEvent.FLAG_UNHANDLED, true);
-            } break;
-            case MSG_DISPATCH_KEY_FROM_IME: {
-                if (LOCAL_LOGV) Log.v(
-                    TAG, "Dispatching key "
-                    + msg.obj + " from IME to " + mView);
-                KeyEvent event = (KeyEvent)msg.obj;
-                if ((event.getFlags()&KeyEvent.FLAG_FROM_SYSTEM) != 0) {
-                    // The IME is trying to say this event is from the
-                    // system!  Bad bad bad!
-                    //noinspection UnusedAssignment
-                    event = KeyEvent.changeFlags(event, event.getFlags() &
-                            ~KeyEvent.FLAG_FROM_SYSTEM);
-                }
-                enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
-            } break;
-            case MSG_CHECK_FOCUS: {
-                InputMethodManager imm = InputMethodManager.peekInstance();
-                if (imm != null) {
-                    imm.checkFocus();
-                }
-            } break;
-            case MSG_CLOSE_SYSTEM_DIALOGS: {
-                if (mView != null) {
-                    mView.onCloseSystemDialogs((String)msg.obj);
-                }
-            } break;
-            case MSG_DISPATCH_DRAG_EVENT:
-            case MSG_DISPATCH_DRAG_LOCATION_EVENT: {
-                DragEvent event = (DragEvent)msg.obj;
-                event.mLocalState = mLocalDragState;    // only present when this app called startDrag()
-                handleDragEvent(event);
-            } break;
-            case MSG_DISPATCH_SYSTEM_UI_VISIBILITY: {
-                handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo) msg.obj);
-            } break;
-            case MSG_UPDATE_CONFIGURATION: {
-                Configuration config = (Configuration) msg.obj;
-                if (config.isOtherSeqNewer(
-                        mLastReportedMergedConfiguration.getMergedConfiguration())) {
-                    // If we already have a newer merged config applied - use its global part.
-                    config = mLastReportedMergedConfiguration.getGlobalConfiguration();
-                }
-
-                // Use the newer global config and last reported override config.
-                mPendingMergedConfiguration.setConfiguration(config,
-                        mLastReportedMergedConfiguration.getOverrideConfiguration());
-
-                performConfigurationChange(mPendingMergedConfiguration, false /* force */,
-                        INVALID_DISPLAY /* same display */);
-            } break;
-            case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
-                setAccessibilityFocus(null, null);
-            } break;
-            case MSG_INVALIDATE_WORLD: {
-                if (mView != null) {
-                    invalidateWorld(mView);
-                }
-            } break;
-            case MSG_DISPATCH_WINDOW_SHOWN: {
-                handleDispatchWindowShown();
-            } break;
-            case MSG_REQUEST_KEYBOARD_SHORTCUTS: {
-                final IResultReceiver receiver = (IResultReceiver) msg.obj;
-                final int deviceId = msg.arg1;
-                handleRequestKeyboardShortcuts(receiver, deviceId);
-            } break;
-            case MSG_UPDATE_POINTER_ICON: {
-                MotionEvent event = (MotionEvent) msg.obj;
-                resetPointerIcon(event);
-            } break;
-            case MSG_POINTER_CAPTURE_CHANGED: {
-                final boolean hasCapture = msg.arg1 != 0;
-                handlePointerCaptureChanged(hasCapture);
-            } break;
-            case MSG_DRAW_FINISHED: {
-                pendingDrawFinished();
-            } break;
+                } break;
+                case MSG_DISPATCH_WINDOW_SHOWN: {
+                    handleDispatchWindowShown();
+                } break;
+                case MSG_REQUEST_KEYBOARD_SHORTCUTS: {
+                    final IResultReceiver receiver = (IResultReceiver) msg.obj;
+                    final int deviceId = msg.arg1;
+                    handleRequestKeyboardShortcuts(receiver, deviceId);
+                } break;
+                case MSG_UPDATE_POINTER_ICON: {
+                    MotionEvent event = (MotionEvent) msg.obj;
+                    resetPointerIcon(event);
+                } break;
+                case MSG_POINTER_CAPTURE_CHANGED: {
+                    final boolean hasCapture = msg.arg1 != 0;
+                    handlePointerCaptureChanged(hasCapture);
+                } break;
+                case MSG_DRAW_FINISHED: {
+                    pendingDrawFinished();
+                } break;
             }
         }
     }
@@ -4203,6 +4208,18 @@
             }
         }
 
+        protected void onWindowFocusChanged(boolean hasWindowFocus) {
+            if (mNext != null) {
+                mNext.onWindowFocusChanged(hasWindowFocus);
+            }
+        }
+
+        protected void onDetachedFromWindow() {
+            if (mNext != null) {
+                mNext.onDetachedFromWindow();
+            }
+        }
+
         protected boolean shouldDropInputEvent(QueuedInputEvent q) {
             if (mView == null || !mAdded) {
                 Slog.w(mTag, "Dropping event due to root view being removed: " + q.mEvent);
@@ -4956,9 +4973,9 @@
                     final MotionEvent event = (MotionEvent)q.mEvent;
                     final int source = event.getSource();
                     if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
-                        mTrackball.cancel(event);
+                        mTrackball.cancel();
                     } else if ((source & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
-                        mJoystick.cancel(event);
+                        mJoystick.cancel();
                     } else if ((source & InputDevice.SOURCE_TOUCH_NAVIGATION)
                             == InputDevice.SOURCE_TOUCH_NAVIGATION) {
                         mTouchNavigation.cancel(event);
@@ -4967,6 +4984,18 @@
             }
             super.onDeliverToNext(q);
         }
+
+        @Override
+        protected void onWindowFocusChanged(boolean hasWindowFocus) {
+            if (!hasWindowFocus) {
+                mJoystick.cancel();
+            }
+        }
+
+        @Override
+        protected void onDetachedFromWindow() {
+            mJoystick.cancel();
+        }
     }
 
     /**
@@ -5079,7 +5108,7 @@
             }
         }
 
-        public void cancel(MotionEvent event) {
+        public void cancel() {
             mLastTime = Integer.MIN_VALUE;
 
             // If we reach this, we consumed a trackball event.
@@ -5263,14 +5292,11 @@
      * Creates dpad events from unhandled joystick movements.
      */
     final class SyntheticJoystickHandler extends Handler {
-        private final static String TAG = "SyntheticJoystickHandler";
         private final static int MSG_ENQUEUE_X_AXIS_KEY_REPEAT = 1;
         private final static int MSG_ENQUEUE_Y_AXIS_KEY_REPEAT = 2;
 
-        private int mLastXDirection;
-        private int mLastYDirection;
-        private int mLastXKeyCode;
-        private int mLastYKeyCode;
+        private final JoystickAxesState mJoystickAxesState = new JoystickAxesState();
+        private final SparseArray<KeyEvent> mDeviceKeyEvents = new SparseArray<>();
 
         public SyntheticJoystickHandler() {
             super(true);
@@ -5281,11 +5307,10 @@
             switch (msg.what) {
                 case MSG_ENQUEUE_X_AXIS_KEY_REPEAT:
                 case MSG_ENQUEUE_Y_AXIS_KEY_REPEAT: {
-                    KeyEvent oldEvent = (KeyEvent)msg.obj;
-                    KeyEvent e = KeyEvent.changeTimeRepeat(oldEvent,
-                            SystemClock.uptimeMillis(),
-                            oldEvent.getRepeatCount() + 1);
                     if (mAttachInfo.mHasWindowFocus) {
+                        KeyEvent oldEvent = (KeyEvent) msg.obj;
+                        KeyEvent e = KeyEvent.changeTimeRepeat(oldEvent,
+                                SystemClock.uptimeMillis(), oldEvent.getRepeatCount() + 1);
                         enqueueInputEvent(e);
                         Message m = obtainMessage(msg.what, e);
                         m.setAsynchronous(true);
@@ -5297,97 +5322,176 @@
 
         public void process(MotionEvent event) {
             switch(event.getActionMasked()) {
-            case MotionEvent.ACTION_CANCEL:
-                cancel(event);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                update(event, true);
-                break;
-            default:
-                Log.w(mTag, "Unexpected action: " + event.getActionMasked());
+                case MotionEvent.ACTION_CANCEL:
+                    cancel();
+                    break;
+                case MotionEvent.ACTION_MOVE:
+                    update(event);
+                    break;
+                default:
+                    Log.w(mTag, "Unexpected action: " + event.getActionMasked());
             }
         }
 
-        private void cancel(MotionEvent event) {
+        private void cancel() {
             removeMessages(MSG_ENQUEUE_X_AXIS_KEY_REPEAT);
             removeMessages(MSG_ENQUEUE_Y_AXIS_KEY_REPEAT);
-            update(event, false);
+            for (int i = 0; i < mDeviceKeyEvents.size(); i++) {
+                final KeyEvent keyEvent = mDeviceKeyEvents.valueAt(i);
+                if (keyEvent != null) {
+                    enqueueInputEvent(KeyEvent.changeTimeRepeat(keyEvent,
+                            SystemClock.uptimeMillis(), 0));
+                }
+            }
+            mDeviceKeyEvents.clear();
+            mJoystickAxesState.resetState();
         }
 
-        private void update(MotionEvent event, boolean synthesizeNewKeys) {
+        private void update(MotionEvent event) {
+            final int historySize = event.getHistorySize();
+            for (int h = 0; h < historySize; h++) {
+                final long time = event.getHistoricalEventTime(h);
+                mJoystickAxesState.updateStateForAxis(event, time, MotionEvent.AXIS_X,
+                        event.getHistoricalAxisValue(MotionEvent.AXIS_X, 0, h));
+                mJoystickAxesState.updateStateForAxis(event, time, MotionEvent.AXIS_Y,
+                        event.getHistoricalAxisValue(MotionEvent.AXIS_Y, 0, h));
+                mJoystickAxesState.updateStateForAxis(event, time, MotionEvent.AXIS_HAT_X,
+                        event.getHistoricalAxisValue(MotionEvent.AXIS_HAT_X, 0, h));
+                mJoystickAxesState.updateStateForAxis(event, time, MotionEvent.AXIS_HAT_Y,
+                        event.getHistoricalAxisValue(MotionEvent.AXIS_HAT_Y, 0, h));
+            }
             final long time = event.getEventTime();
-            final int metaState = event.getMetaState();
-            final int deviceId = event.getDeviceId();
-            final int source = event.getSource();
-
-            int xDirection = joystickAxisValueToDirection(
+            mJoystickAxesState.updateStateForAxis(event, time, MotionEvent.AXIS_X,
+                    event.getAxisValue(MotionEvent.AXIS_X));
+            mJoystickAxesState.updateStateForAxis(event, time, MotionEvent.AXIS_Y,
+                    event.getAxisValue(MotionEvent.AXIS_Y));
+            mJoystickAxesState.updateStateForAxis(event, time, MotionEvent.AXIS_HAT_X,
                     event.getAxisValue(MotionEvent.AXIS_HAT_X));
-            if (xDirection == 0) {
-                xDirection = joystickAxisValueToDirection(event.getX());
-            }
-
-            int yDirection = joystickAxisValueToDirection(
+            mJoystickAxesState.updateStateForAxis(event, time, MotionEvent.AXIS_HAT_Y,
                     event.getAxisValue(MotionEvent.AXIS_HAT_Y));
-            if (yDirection == 0) {
-                yDirection = joystickAxisValueToDirection(event.getY());
-            }
-
-            if (xDirection != mLastXDirection) {
-                if (mLastXKeyCode != 0) {
-                    removeMessages(MSG_ENQUEUE_X_AXIS_KEY_REPEAT);
-                    enqueueInputEvent(new KeyEvent(time, time,
-                            KeyEvent.ACTION_UP, mLastXKeyCode, 0, metaState,
-                            deviceId, 0, KeyEvent.FLAG_FALLBACK, source));
-                    mLastXKeyCode = 0;
-                }
-
-                mLastXDirection = xDirection;
-
-                if (xDirection != 0 && synthesizeNewKeys) {
-                    mLastXKeyCode = xDirection > 0
-                            ? KeyEvent.KEYCODE_DPAD_RIGHT : KeyEvent.KEYCODE_DPAD_LEFT;
-                    final KeyEvent e = new KeyEvent(time, time,
-                            KeyEvent.ACTION_DOWN, mLastXKeyCode, 0, metaState,
-                            deviceId, 0, KeyEvent.FLAG_FALLBACK, source);
-                    enqueueInputEvent(e);
-                    Message m = obtainMessage(MSG_ENQUEUE_X_AXIS_KEY_REPEAT, e);
-                    m.setAsynchronous(true);
-                    sendMessageDelayed(m, ViewConfiguration.getKeyRepeatTimeout());
-                }
-            }
-
-            if (yDirection != mLastYDirection) {
-                if (mLastYKeyCode != 0) {
-                    removeMessages(MSG_ENQUEUE_Y_AXIS_KEY_REPEAT);
-                    enqueueInputEvent(new KeyEvent(time, time,
-                            KeyEvent.ACTION_UP, mLastYKeyCode, 0, metaState,
-                            deviceId, 0, KeyEvent.FLAG_FALLBACK, source));
-                    mLastYKeyCode = 0;
-                }
-
-                mLastYDirection = yDirection;
-
-                if (yDirection != 0 && synthesizeNewKeys) {
-                    mLastYKeyCode = yDirection > 0
-                            ? KeyEvent.KEYCODE_DPAD_DOWN : KeyEvent.KEYCODE_DPAD_UP;
-                    final KeyEvent e = new KeyEvent(time, time,
-                            KeyEvent.ACTION_DOWN, mLastYKeyCode, 0, metaState,
-                            deviceId, 0, KeyEvent.FLAG_FALLBACK, source);
-                    enqueueInputEvent(e);
-                    Message m = obtainMessage(MSG_ENQUEUE_Y_AXIS_KEY_REPEAT, e);
-                    m.setAsynchronous(true);
-                    sendMessageDelayed(m, ViewConfiguration.getKeyRepeatTimeout());
-                }
-            }
         }
 
-        private int joystickAxisValueToDirection(float value) {
-            if (value >= 0.5f) {
-                return 1;
-            } else if (value <= -0.5f) {
-                return -1;
-            } else {
-                return 0;
+        final class JoystickAxesState {
+            // State machine: from neutral state (no button press) can go into
+            // button STATE_UP_OR_LEFT or STATE_DOWN_OR_RIGHT state, emitting an ACTION_DOWN event.
+            // From STATE_UP_OR_LEFT or STATE_DOWN_OR_RIGHT state can go into neutral state,
+            // emitting an ACTION_UP event.
+            private static final int STATE_UP_OR_LEFT = -1;
+            private static final int STATE_NEUTRAL = 0;
+            private static final int STATE_DOWN_OR_RIGHT = 1;
+
+            final int[] mAxisStatesHat = {STATE_NEUTRAL, STATE_NEUTRAL}; // {AXIS_HAT_X, AXIS_HAT_Y}
+            final int[] mAxisStatesStick = {STATE_NEUTRAL, STATE_NEUTRAL}; // {AXIS_X, AXIS_Y}
+
+            void resetState() {
+                mAxisStatesHat[0] = STATE_NEUTRAL;
+                mAxisStatesHat[1] = STATE_NEUTRAL;
+                mAxisStatesStick[0] = STATE_NEUTRAL;
+                mAxisStatesStick[1] = STATE_NEUTRAL;
+            }
+
+            void updateStateForAxis(MotionEvent event, long time, int axis, float value) {
+                // Emit KeyEvent if necessary
+                // axis can be AXIS_X, AXIS_Y, AXIS_HAT_X, AXIS_HAT_Y
+                final int axisStateIndex;
+                final int repeatMessage;
+                if (isXAxis(axis)) {
+                    axisStateIndex = 0;
+                    repeatMessage = MSG_ENQUEUE_X_AXIS_KEY_REPEAT;
+                } else if (isYAxis(axis)) {
+                    axisStateIndex = 1;
+                    repeatMessage = MSG_ENQUEUE_Y_AXIS_KEY_REPEAT;
+                } else {
+                    Log.e(mTag, "Unexpected axis " + axis + " in updateStateForAxis!");
+                    return;
+                }
+                final int newState = joystickAxisValueToState(value);
+
+                final int currentState;
+                if (axis == MotionEvent.AXIS_X || axis == MotionEvent.AXIS_Y) {
+                    currentState = mAxisStatesStick[axisStateIndex];
+                } else {
+                    currentState = mAxisStatesHat[axisStateIndex];
+                }
+
+                if (currentState == newState) {
+                    return;
+                }
+
+                final int metaState = event.getMetaState();
+                final int deviceId = event.getDeviceId();
+                final int source = event.getSource();
+
+                if (currentState == STATE_DOWN_OR_RIGHT || currentState == STATE_UP_OR_LEFT) {
+                    // send a button release event
+                    final int keyCode = joystickAxisAndStateToKeycode(axis, currentState);
+                    if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
+                        enqueueInputEvent(new KeyEvent(time, time, KeyEvent.ACTION_UP, keyCode,
+                                0, metaState, deviceId, 0, KeyEvent.FLAG_FALLBACK, source));
+                        // remove the corresponding pending UP event if focus lost/view detached
+                        mDeviceKeyEvents.put(deviceId, null);
+                    }
+                    removeMessages(repeatMessage);
+                }
+
+                if (newState == STATE_DOWN_OR_RIGHT || newState == STATE_UP_OR_LEFT) {
+                    // send a button down event
+                    final int keyCode = joystickAxisAndStateToKeycode(axis, newState);
+                    if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
+                        KeyEvent keyEvent = new KeyEvent(time, time, KeyEvent.ACTION_DOWN, keyCode,
+                                0, metaState, deviceId, 0, KeyEvent.FLAG_FALLBACK, source);
+                        enqueueInputEvent(keyEvent);
+                        Message m = obtainMessage(repeatMessage, keyEvent);
+                        m.setAsynchronous(true);
+                        sendMessageDelayed(m, ViewConfiguration.getKeyRepeatTimeout());
+                        // store the corresponding ACTION_UP event so that it can be sent
+                        // if focus is lost or root view is removed
+                        mDeviceKeyEvents.put(deviceId,
+                                new KeyEvent(time, time, KeyEvent.ACTION_UP, keyCode,
+                                        0, metaState, deviceId, 0,
+                                        KeyEvent.FLAG_FALLBACK | KeyEvent.FLAG_CANCELED,
+                                        source));
+                    }
+                }
+                if (axis == MotionEvent.AXIS_X || axis == MotionEvent.AXIS_Y) {
+                    mAxisStatesStick[axisStateIndex] = newState;
+                } else {
+                    mAxisStatesHat[axisStateIndex] = newState;
+                }
+            }
+
+            private boolean isXAxis(int axis) {
+                return axis == MotionEvent.AXIS_X || axis == MotionEvent.AXIS_HAT_X;
+            }
+            private boolean isYAxis(int axis) {
+                return axis == MotionEvent.AXIS_Y || axis == MotionEvent.AXIS_HAT_Y;
+            }
+
+            private int joystickAxisAndStateToKeycode(int axis, int state) {
+                if (isXAxis(axis) && state == STATE_UP_OR_LEFT) {
+                    return KeyEvent.KEYCODE_DPAD_LEFT;
+                }
+                if (isXAxis(axis) && state == STATE_DOWN_OR_RIGHT) {
+                    return KeyEvent.KEYCODE_DPAD_RIGHT;
+                }
+                if (isYAxis(axis) && state == STATE_UP_OR_LEFT) {
+                    return KeyEvent.KEYCODE_DPAD_UP;
+                }
+                if (isYAxis(axis) && state == STATE_DOWN_OR_RIGHT) {
+                    return KeyEvent.KEYCODE_DPAD_DOWN;
+                }
+                Log.e(mTag, "Unknown axis " + axis + " or direction " + state);
+                return KeyEvent.KEYCODE_UNKNOWN; // should never happen
+            }
+
+            private int joystickAxisValueToState(float value) {
+                if (value >= 0.5f) {
+                    return STATE_DOWN_OR_RIGHT;
+                } else if (value <= -0.5f) {
+                    return STATE_UP_OR_LEFT;
+                } else {
+                    return STATE_NEUTRAL;
+                }
             }
         }
     }
@@ -6108,7 +6212,6 @@
             if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
         }
 
-        //Log.d(mTag, ">>>>>> CALLING relayout");
         if (params != null && mOrigWindowType != params.type) {
             // For compatibility with old apps, don't crash here.
             if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
@@ -6129,7 +6232,6 @@
         mPendingAlwaysConsumeNavBar =
                 (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0;
 
-        //Log.d(mTag, "<<<<<< BACK FROM relayout");
         if (restore) {
             params.restore();
         }
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index f671c34..309366c 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -365,6 +365,30 @@
     public abstract void setDataIsSensitive(boolean sensitive);
 
     /**
+     * Sets the minimum width in ems of the text associated with this view, when supported.
+     *
+     * <p>Should only be set when the node is used for autofill purposes - it will be ignored
+     * when used for Assist.
+     */
+    public abstract void setMinTextEms(int minEms);
+
+    /**
+     * Sets the maximum width in ems of the text associated with this view, when supported.
+     *
+     * <p>Should only be set when the node is used for autofill purposes - it will be ignored
+     * when used for Assist.
+     */
+    public abstract void setMaxTextEms(int maxEms);
+
+    /**
+     * Sets the maximum length of the text associated with this view, when supported.
+     *
+     * <p>Should only be set when the node is used for autofill purposes - it will be ignored
+     * when used for Assist.
+     */
+    public abstract void setMaxTextLength(int maxLength);
+
+    /**
      * Call when done populating a {@link ViewStructure} returned by
      * {@link #asyncNewChild}.
      */
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 98f8dc8..69cc100 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -335,8 +335,8 @@
     public abstract void setOnHardKeyboardStatusChangeListener(
         OnHardKeyboardStatusChangeListener listener);
 
-    /** Returns true if the stack with the input Id is currently visible. */
-    public abstract boolean isStackVisible(int stackId);
+    /** Returns true if a stack in the windowing mode is currently visible. */
+    public abstract boolean isStackVisible(int windowingMode);
 
     /**
      * @return True if and only if the docked divider is currently in resize mode.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index da72535..137e551 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -467,11 +467,8 @@
          */
         public boolean isDimming();
 
-        /**
-         * @return the stack id this windows belongs to, or {@link StackId#INVALID_STACK_ID} if
-         *         not attached to any stack.
-         */
-        int getStackId();
+        /** @return the current windowing mode of this window. */
+        int getWindowingMode();
 
         /**
          * Returns true if the window is current in multi-windowing mode. i.e. it shares the
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index 0f21c5c..d785117 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -329,8 +329,6 @@
                 final long oldParentId = oldInfo.getParentNodeId();
                 if (info.getParentNodeId() != oldParentId) {
                     clearSubTreeLocked(windowId, oldParentId);
-                } else {
-                    oldInfo.recycle();
                 }
            }
 
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 4fb2a99..44f304d 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -91,10 +91,10 @@
  * </ul>
  *
  * <p>When the service returns datasets, the Android System displays an autofill dataset picker
- * UI affordance associated with the view, when the view is focused on and is part of a dataset.
- * The application can be notified when the affordance is shown by registering an
+ * UI associated with the view, when the view is focused on and is part of a dataset.
+ * The application can be notified when the UI is shown by registering an
  * {@link AutofillCallback} through {@link #registerCallback(AutofillCallback)}. When the user
- * selects a dataset from the affordance, all views present in the dataset are autofilled, through
+ * selects a dataset from the UI, all views present in the dataset are autofilled, through
  * calls to {@link View#autofill(AutofillValue)} or {@link View#autofill(SparseArray)}.
  *
  * <p>When the service returns ids of savable views, the Android System keeps track of changes
@@ -108,7 +108,7 @@
  * </ul>
  *
  * <p>Finally, after the autofill context is commited (i.e., not cancelled), the Android System
- * shows a save UI affordance if the value of savable views have changed. If the user selects the
+ * shows an autofill save UI if the value of savable views have changed. If the user selects the
  * option to Save, the current value of the views is then sent to the autofill service.
  *
  * <p>It is safe to call into its methods from any thread.
@@ -150,6 +150,12 @@
      * service authentication will contain the Bundle set by
      * {@link android.service.autofill.FillResponse.Builder#setClientState(Bundle)} on this extra.
      *
+     * <p>On Android {@link android.os.Build.VERSION_CODES#P} and higher, the autofill service
+     * can also add this bundle to the {@link Intent} set as the
+     * {@link android.app.Activity#setResult(int, Intent) result} for an authentication request,
+     * so the bundle can be recovered later on
+     * {@link android.service.autofill.SaveRequest#getClientState()}.
+     *
      * <p>
      * Type: {@link android.os.Bundle}
      */
@@ -311,6 +317,14 @@
     @GuardedBy("mLock")
     @Nullable private ArraySet<AutofillId> mFillableIds;
 
+    /** If set, session is commited when the field is clicked. */
+    @GuardedBy("mLock")
+    @Nullable private AutofillId mSaveTriggerId;
+
+    /** If set, session is commited when the activity is finished; otherwise session is canceled. */
+    @GuardedBy("mLock")
+    private boolean mSaveOnFinish;
+
     /** @hide */
     public interface AutofillClient {
         /**
@@ -834,6 +848,46 @@
         }
     }
 
+
+    /**
+     * Called when a {@link View} is clicked. Currently only used by views that should trigger save.
+     *
+     * @hide
+     */
+    public void notifyViewClicked(View view) {
+        final AutofillId id = view.getAutofillId();
+
+        if (sVerbose) Log.v(TAG, "notifyViewClicked(): id=" + id + ", trigger=" + mSaveTriggerId);
+
+        synchronized (mLock) {
+            if (mSaveTriggerId != null && mSaveTriggerId.equals(id)) {
+                if (sDebug) Log.d(TAG, "triggering commit by click of " + id);
+                commitLocked();
+                mMetricsLogger.action(MetricsEvent.AUTOFILL_SAVE_EXPLICITLY_TRIGGERED,
+                        mContext.getPackageName());
+            }
+        }
+    }
+
+    /**
+     * Called by {@link android.app.Activity} to commit or cancel the session on finish.
+     *
+     * @hide
+     */
+    public void onActivityFinished() {
+        if (!hasAutofillFeature()) {
+            return;
+        }
+        synchronized (mLock) {
+            if (mSaveOnFinish) {
+                commitLocked();
+            } else {
+                if (sDebug) Log.d(TAG, "Cancelling session on finish() as requested by service");
+                cancelLocked();
+            }
+        }
+    }
+
     /**
      * Called to indicate the current autofill context should be commited.
      *
@@ -850,14 +904,17 @@
             return;
         }
         synchronized (mLock) {
-            if (!mEnabled && !isActiveLocked()) {
-                return;
-            }
-
-            finishSessionLocked();
+            commitLocked();
         }
     }
 
+    private void commitLocked() {
+        if (!mEnabled && !isActiveLocked()) {
+            return;
+        }
+        finishSessionLocked();
+    }
+
     /**
      * Called to indicate the current autofill context should be cancelled.
      *
@@ -874,14 +931,17 @@
             return;
         }
         synchronized (mLock) {
-            if (!mEnabled && !isActiveLocked()) {
-                return;
-            }
-
-            cancelSessionLocked();
+            cancelLocked();
         }
     }
 
+    private void cancelLocked() {
+        if (!mEnabled && !isActiveLocked()) {
+            return;
+        }
+        cancelSessionLocked();
+    }
+
     /** @hide */
     public void disableOwnedAutofillServices() {
         disableAutofillServices();
@@ -959,6 +1019,10 @@
             final Parcelable result = data.getParcelableExtra(EXTRA_AUTHENTICATION_RESULT);
             final Bundle responseData = new Bundle();
             responseData.putParcelable(EXTRA_AUTHENTICATION_RESULT, result);
+            final Bundle newClientState = data.getBundleExtra(EXTRA_CLIENT_STATE);
+            if (newClientState != null) {
+                responseData.putBundle(EXTRA_CLIENT_STATE, newClientState);
+            }
             try {
                 mService.setAuthenticationResult(responseData, mSessionId, authenticationId,
                         mContext.getUserId());
@@ -1038,6 +1102,7 @@
         mState = STATE_UNKNOWN;
         mTrackedViews = null;
         mFillableIds = null;
+        mSaveTriggerId = null;
     }
 
     private void updateSessionLocked(AutofillId id, Rect bounds, AutofillValue value, int action,
@@ -1289,12 +1354,15 @@
     /**
      *  Set the tracked views.
      *
-     * @param trackedIds The views to be tracked
+     * @param trackedIds The views to be tracked.
      * @param saveOnAllViewsInvisible Finish the session once all tracked views are invisible.
+     * @param saveOnFinish Finish the session once the activity is finished.
      * @param fillableIds Views that might anchor FillUI.
+     * @param saveTriggerId View that when clicked triggers commit().
      */
     private void setTrackedViews(int sessionId, @Nullable AutofillId[] trackedIds,
-            boolean saveOnAllViewsInvisible, @Nullable AutofillId[] fillableIds) {
+            boolean saveOnAllViewsInvisible, boolean saveOnFinish,
+            @Nullable AutofillId[] fillableIds, @Nullable AutofillId saveTriggerId) {
         synchronized (mLock) {
             if (mEnabled && mSessionId == sessionId) {
                 if (saveOnAllViewsInvisible) {
@@ -1302,6 +1370,7 @@
                 } else {
                     mTrackedViews = null;
                 }
+                mSaveOnFinish = saveOnFinish;
                 if (fillableIds != null) {
                     if (mFillableIds == null) {
                         mFillableIds = new ArraySet<>(fillableIds.length);
@@ -1314,10 +1383,30 @@
                                 + ", mFillableIds" + mFillableIds);
                     }
                 }
+
+                if (mSaveTriggerId != null && !mSaveTriggerId.equals(saveTriggerId)) {
+                    // Turn off trigger on previous view id.
+                    setNotifyOnClickLocked(mSaveTriggerId, false);
+                }
+
+                if (saveTriggerId != null && !saveTriggerId.equals(mSaveTriggerId)) {
+                    // Turn on trigger on new view id.
+                    mSaveTriggerId = saveTriggerId;
+                    setNotifyOnClickLocked(mSaveTriggerId, true);
+                }
             }
         }
     }
 
+    private void setNotifyOnClickLocked(@NonNull AutofillId id, boolean notify) {
+        final View view = findView(id);
+        if (view == null) {
+            Log.w(TAG, "setNotifyOnClick(): invalid id: " + id);
+            return;
+        }
+        view.setNotifyAutofillManagerOnClick(notify);
+    }
+
     private void setSaveUiState(int sessionId, boolean shown) {
         if (sDebug) Log.d(TAG, "setSaveUiState(" + sessionId + "): " + shown);
         synchronized (mLock) {
@@ -1504,6 +1593,8 @@
             pw.print(pfx2); pw.print("invisible:"); pw.println(mTrackedViews.mInvisibleTrackedIds);
         }
         pw.print(pfx); pw.print("fillable ids: "); pw.println(mFillableIds);
+        pw.print(pfx); pw.print("save trigger id: "); pw.println(mSaveTriggerId);
+        pw.print(pfx); pw.print("save on finish(): "); pw.println(mSaveOnFinish);
     }
 
     private String getStateAsStringLocked() {
@@ -1752,7 +1843,7 @@
      * Callback for autofill related events.
      *
      * <p>Typically used for applications that display their own "auto-complete" views, so they can
-     * enable / disable such views when the autofill UI affordance is shown / hidden.
+     * enable / disable such views when the autofill UI is shown / hidden.
      */
     public abstract static class AutofillCallback {
 
@@ -1762,26 +1853,26 @@
         public @interface AutofillEventType {}
 
         /**
-         * The autofill input UI affordance associated with the view was shown.
+         * The autofill input UI associated with the view was shown.
          *
-         * <p>If the view provides its own auto-complete UI affordance and its currently shown, it
+         * <p>If the view provides its own auto-complete UI and its currently shown, it
          * should be hidden upon receiving this event.
          */
         public static final int EVENT_INPUT_SHOWN = 1;
 
         /**
-         * The autofill input UI affordance associated with the view was hidden.
+         * The autofill input UI associated with the view was hidden.
          *
-         * <p>If the view provides its own auto-complete UI affordance that was hidden upon a
+         * <p>If the view provides its own auto-complete UI that was hidden upon a
          * {@link #EVENT_INPUT_SHOWN} event, it could be shown again now.
          */
         public static final int EVENT_INPUT_HIDDEN = 2;
 
         /**
-         * The autofill input UI affordance associated with the view isn't shown because
+         * The autofill input UI associated with the view isn't shown because
          * autofill is not available.
          *
-         * <p>If the view provides its own auto-complete UI affordance but was not displaying it
+         * <p>If the view provides its own auto-complete UI but was not displaying it
          * to avoid flickering, it could shown it upon receiving this event.
          */
         public static final int EVENT_INPUT_UNAVAILABLE = 3;
@@ -1883,12 +1974,12 @@
 
         @Override
         public void setTrackedViews(int sessionId, AutofillId[] ids,
-                boolean saveOnAllViewsInvisible, AutofillId[] fillableIds) {
+                boolean saveOnAllViewsInvisible, boolean saveOnFinish, AutofillId[] fillableIds,
+                AutofillId saveTriggerId) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.post(() ->
-                        afm.setTrackedViews(sessionId, ids, saveOnAllViewsInvisible, fillableIds)
-                );
+                afm.post(() -> afm.setTrackedViews(sessionId, ids, saveOnAllViewsInvisible,
+                        saveOnFinish, fillableIds, saveTriggerId));
             }
         }
 
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 3dabcec..56a22c22 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -53,7 +53,8 @@
       * the session is finished automatically.
       */
     void setTrackedViews(int sessionId, in @nullable AutofillId[] savableIds,
-            boolean saveOnAllViewsInvisible, in @nullable AutofillId[] fillableIds);
+            boolean saveOnAllViewsInvisible, boolean saveOnFinish,
+            in @nullable AutofillId[] fillableIds, in AutofillId saveTriggerId);
 
     /**
      * Requests showing the fill UI.
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index bb1e693..c3601d9 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -152,4 +152,12 @@
      */
     @WorkerThread
     default void logEvent(String source, String event) {}
+
+    /**
+     * Returns this TextClassifier's settings.
+     * @hide
+     */
+    default TextClassifierConstants getSettings() {
+        return TextClassifierConstants.DEFAULT;
+    }
 }
diff --git a/core/java/android/view/textclassifier/TextClassifierConstants.java b/core/java/android/view/textclassifier/TextClassifierConstants.java
new file mode 100644
index 0000000..51e6168
--- /dev/null
+++ b/core/java/android/view/textclassifier/TextClassifierConstants.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 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 android.view.textclassifier;
+
+import android.annotation.Nullable;
+import android.util.KeyValueListParser;
+import android.util.Slog;
+
+/**
+ * TextClassifier specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * <pre>
+ * smart_selection_dark_launch              (boolean)
+ * smart_selection_enabled_for_edit_text    (boolean)
+ * </pre>
+ *
+ * <p>
+ * Type: string
+ * see also android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS
+ *
+ * Example of setting the values for testing.
+ * adb shell settings put global text_classifier_constants smart_selection_dark_launch=true,smart_selection_enabled_for_edit_text=true
+ * @hide
+ */
+public final class TextClassifierConstants {
+
+    private static final String LOG_TAG = "TextClassifierConstants";
+
+    private static final String SMART_SELECTION_DARK_LAUNCH =
+            "smart_selection_dark_launch";
+    private static final String SMART_SELECTION_ENABLED_FOR_EDIT_TEXT =
+            "smart_selection_enabled_for_edit_text";
+
+    private static final boolean SMART_SELECTION_DARK_LAUNCH_DEFAULT = false;
+    private static final boolean SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT = true;
+
+    /** Default settings. */
+    static final TextClassifierConstants DEFAULT = new TextClassifierConstants();
+
+    private final boolean mDarkLaunch;
+    private final boolean mSuggestSelectionEnabledForEditableText;
+
+    private TextClassifierConstants() {
+        mDarkLaunch = SMART_SELECTION_DARK_LAUNCH_DEFAULT;
+        mSuggestSelectionEnabledForEditableText = SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT;
+    }
+
+    private TextClassifierConstants(@Nullable String settings) {
+        final KeyValueListParser parser = new KeyValueListParser(',');
+        try {
+            parser.setString(settings);
+        } catch (IllegalArgumentException e) {
+            // Failed to parse the settings string, log this and move on with defaults.
+            Slog.e(LOG_TAG, "Bad TextClassifier settings: " + settings);
+        }
+        mDarkLaunch = parser.getBoolean(
+                SMART_SELECTION_DARK_LAUNCH,
+                SMART_SELECTION_DARK_LAUNCH_DEFAULT);
+        mSuggestSelectionEnabledForEditableText = parser.getBoolean(
+                SMART_SELECTION_ENABLED_FOR_EDIT_TEXT,
+                SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT);
+    }
+
+    static TextClassifierConstants loadFromString(String settings) {
+        return new TextClassifierConstants(settings);
+    }
+
+    public boolean isDarkLaunch() {
+        return mDarkLaunch;
+    }
+
+    public boolean isSuggestSelectionEnabledForEditableText() {
+        return mSuggestSelectionEnabledForEditableText;
+    }
+}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 2aa81a2..ef08747 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -24,12 +24,12 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Drawable;
-import android.icu.text.BreakIterator;
 import android.net.Uri;
 import android.os.LocaleList;
 import android.os.ParcelFileDescriptor;
 import android.provider.Browser;
 import android.provider.ContactsContract;
+import android.provider.Settings;
 import android.text.Spannable;
 import android.text.TextUtils;
 import android.text.method.WordIterator;
@@ -47,6 +47,7 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.text.BreakIterator;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -91,6 +92,8 @@
     @GuardedBy("mSmartSelectionLock") // Do not access outside this lock.
     private SmartSelection mSmartSelection;
 
+    private TextClassifierConstants mSettings;
+
     TextClassifierImpl(Context context) {
         mContext = Preconditions.checkNotNull(context);
     }
@@ -189,6 +192,15 @@
         }
     }
 
+    @Override
+    public TextClassifierConstants getSettings() {
+        if (mSettings == null) {
+            mSettings = TextClassifierConstants.loadFromString(Settings.Global.getString(
+                    mContext.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
+        }
+        return mSettings;
+    }
+
     private SmartSelection getSmartSelection(LocaleList localeList) throws FileNotFoundException {
         synchronized (mSmartSelectionLock) {
             localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index afd1188..91f6799 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -165,7 +165,7 @@
     private static final int MENU_ITEM_ORDER_PASTE_AS_PLAIN_TEXT = 11;
     private static final int MENU_ITEM_ORDER_PROCESS_TEXT_INTENT_ACTIONS_START = 100;
 
-    private static final float MAGNIFIER_ZOOM = 1.5f;
+    private static final float MAGNIFIER_ZOOM = 1.25f;
     @IntDef({MagnifierHandleTrigger.SELECTION_START,
             MagnifierHandleTrigger.SELECTION_END,
             MagnifierHandleTrigger.INSERTION})
@@ -4550,12 +4550,14 @@
             final float centerYOnScreen = yPosInView + mTextView.getTotalPaddingTop()
                     - mTextView.getScrollY() + coordinatesOnScreen[1];
 
+            suspendBlink();
             mMagnifier.show(centerXOnScreen, centerYOnScreen, MAGNIFIER_ZOOM);
         }
 
         protected final void dismissMagnifier() {
             if (mMagnifier != null) {
                 mMagnifier.dismiss();
+                resumeBlink();
             }
         }
 
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 1b26f8e..199b596 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -2653,7 +2653,11 @@
     /**
      * Equivalent to calling
      * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
-     * to launch the provided {@link PendingIntent}.
+     * to launch the provided {@link PendingIntent}. The source bounds
+     * ({@link Intent#getSourceBounds()}) of the intent will be set to the bounds of the clicked
+     * view in screen space.
+     * Note that any activity options associated with the pendingIntent may get overridden
+     * before starting the intent.
      *
      * When setting the on-click action of items within collections (eg. {@link ListView},
      * {@link StackView} etc.), this method will not work. Instead, use {@link
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 3be42a5..5e22650 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -95,11 +95,15 @@
     }
 
     public void startActionModeAsync(boolean adjustSelection) {
+        // Check if the smart selection should run for editable text.
+        adjustSelection &= !mTextView.isTextEditable()
+                || mTextView.getTextClassifier().getSettings()
+                        .isSuggestSelectionEnabledForEditableText();
+
         mSelectionTracker.onOriginalSelection(
                 getText(mTextView),
                 mTextView.getSelectionStart(),
-                mTextView.getSelectionEnd(),
-                mTextView.isTextEditable());
+                mTextView.getSelectionEnd());
         cancelAsyncTask();
         if (skipTextClassification()) {
             startActionMode(null);
@@ -196,7 +200,10 @@
     private void startActionMode(@Nullable SelectionResult result) {
         final CharSequence text = getText(mTextView);
         if (result != null && text instanceof Spannable) {
-            Selection.setSelection((Spannable) text, result.mStart, result.mEnd);
+            // Do not change the selection if TextClassifier should be dark launched.
+            if (!mTextView.getTextClassifier().getSettings().isDarkLaunch()) {
+                Selection.setSelection((Spannable) text, result.mStart, result.mEnd);
+            }
             mTextClassification = result.mClassification;
         } else {
             mTextClassification = null;
@@ -377,7 +384,7 @@
     }
 
     private void resetTextClassificationHelper() {
-        mTextClassificationHelper.reset(
+        mTextClassificationHelper.init(
                 mTextView.getTextClassifier(),
                 getText(mTextView),
                 mTextView.getSelectionStart(), mTextView.getSelectionEnd(),
@@ -415,8 +422,7 @@
         /**
          * Called when the original selection happens, before smart selection is triggered.
          */
-        public void onOriginalSelection(
-                CharSequence text, int selectionStart, int selectionEnd, boolean editableText) {
+        public void onOriginalSelection(CharSequence text, int selectionStart, int selectionEnd) {
             // If we abandoned a selection and created a new one very shortly after, we may still
             // have a pending request to log ABANDON, which we flush here.
             mDelayedLogAbandon.flush();
@@ -812,11 +818,11 @@
 
         TextClassificationHelper(TextClassifier textClassifier,
                 CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
-            reset(textClassifier, text, selectionStart, selectionEnd, locales);
+            init(textClassifier, text, selectionStart, selectionEnd, locales);
         }
 
         @UiThread
-        public void reset(TextClassifier textClassifier,
+        public void init(TextClassifier textClassifier,
                 CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
             mTextClassifier = Preconditions.checkNotNull(textClassifier);
             mText = Preconditions.checkNotNull(text).toString();
@@ -839,8 +845,12 @@
             trimText();
             final TextSelection selection = mTextClassifier.suggestSelection(
                     mTrimmedText, mRelativeStart, mRelativeEnd, mLocales);
-            mSelectionStart = Math.max(0, selection.getSelectionStartIndex() + mTrimStart);
-            mSelectionEnd = Math.min(mText.length(), selection.getSelectionEndIndex() + mTrimStart);
+            // Do not classify new selection boundaries if TextClassifier should be dark launched.
+            if (!mTextClassifier.getSettings().isDarkLaunch()) {
+                mSelectionStart = Math.max(0, selection.getSelectionStartIndex() + mTrimStart);
+                mSelectionEnd = Math.min(
+                        mText.length(), selection.getSelectionEndIndex() + mTrimStart);
+            }
             return performClassification(selection);
         }
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 24ae03c..d9bc51f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10338,6 +10338,17 @@
                 // of the View (and can be any drawable) or a BackgroundColorSpan inside the text.
                 structure.setTextStyle(getTextSize(), getCurrentTextColor(),
                         AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style);
+            } else {
+                structure.setMinTextEms(getMinEms());
+                structure.setMaxTextEms(getMaxEms());
+                int maxLength = -1;
+                for (InputFilter filter: getFilters()) {
+                    if (filter instanceof InputFilter.LengthFilter) {
+                        maxLength = ((InputFilter.LengthFilter) filter).getMax();
+                        break;
+                    }
+                }
+                structure.setMaxTextLength(maxLength);
             }
         }
         structure.setHint(getHint());
diff --git a/core/java/com/android/internal/alsa/AlsaCardsParser.java b/core/java/com/android/internal/alsa/AlsaCardsParser.java
index 5b92a17..bb75bf6 100644
--- a/core/java/com/android/internal/alsa/AlsaCardsParser.java
+++ b/core/java/com/android/internal/alsa/AlsaCardsParser.java
@@ -37,6 +37,12 @@
 
     private ArrayList<AlsaCardRecord> mCardRecords = new ArrayList<AlsaCardRecord>();
 
+    public static final int SCANSTATUS_NOTSCANNED = -1;
+    public static final int SCANSTATUS_SUCCESS = 0;
+    public static final int SCANSTATUS_FAIL = 1;
+    public static final int SCANSTATUS_EMPTY = 2;
+    private int mScanStatus = SCANSTATUS_NOTSCANNED;
+
     public class AlsaCardRecord {
         private static final String TAG = "AlsaCardRecord";
         private static final String kUsbCardKeyStr = "at usb-";
@@ -104,10 +110,11 @@
 
     public AlsaCardsParser() {}
 
-    public void scan() {
+    public int scan() {
         if (DEBUG) {
-            Slog.i(TAG, "AlsaCardsParser.scan()");
+            Slog.i(TAG, "AlsaCardsParser.scan()....");
         }
+
         mCardRecords = new ArrayList<AlsaCardRecord>();
 
         File cardsFile = new File(kCardsFilePath);
@@ -134,11 +141,26 @@
                 mCardRecords.add(cardRecord);
             }
             reader.close();
+            if (mCardRecords.size() > 0) {
+                mScanStatus = SCANSTATUS_SUCCESS;
+            } else {
+                mScanStatus = SCANSTATUS_EMPTY;
+            }
         } catch (FileNotFoundException e) {
             e.printStackTrace();
+            mScanStatus = SCANSTATUS_FAIL;
         } catch (IOException e) {
             e.printStackTrace();
+            mScanStatus = SCANSTATUS_FAIL;
         }
+        if (DEBUG) {
+            Slog.i(TAG, "  status:" + mScanStatus);
+        }
+        return mScanStatus;
+    }
+
+    public int getScanStatus() {
+        return mScanStatus;
     }
 
     public ArrayList<AlsaCardRecord> getScanRecords() {
@@ -182,7 +204,11 @@
         }
 
         // get the new list of devices
-        scan();
+        if (scan() != SCANSTATUS_SUCCESS) {
+            Slog.e(TAG, "Error scanning Alsa cards file.");
+            return -1;
+        }
+
         if (DEBUG) {
             LogDevices("Current Devices:", mCardRecords);
         }
diff --git a/core/java/com/android/internal/alsa/AlsaDevicesParser.java b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
index 6e3d596..15261baf 100644
--- a/core/java/com/android/internal/alsa/AlsaDevicesParser.java
+++ b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
@@ -46,6 +46,12 @@
     private boolean mHasPlaybackDevices = false;
     private boolean mHasMIDIDevices = false;
 
+    public static final int SCANSTATUS_NOTSCANNED = -1;
+    public static final int SCANSTATUS_SUCCESS = 0;
+    public static final int SCANSTATUS_FAIL = 1;
+    public static final int SCANSTATUS_EMPTY = 2;
+    private int mScanStatus = SCANSTATUS_NOTSCANNED;
+
     public class AlsaDeviceRecord {
         public static final int kDeviceType_Unknown = -1;
         public static final int kDeviceType_Audio = 0;
@@ -258,7 +264,11 @@
         return line.charAt(kIndex_CardDeviceField) == '[';
     }
 
-    public boolean scan() {
+    public int scan() {
+        if (DEBUG) {
+            Slog.i(TAG, "AlsaDevicesParser.scan()....");
+        }
+
         mDeviceRecords.clear();
 
         File devicesFile = new File(kDevicesFilePath);
@@ -274,13 +284,27 @@
                 }
             }
             reader.close();
-            return true;
+            // success if we add at least 1 record
+            if (mDeviceRecords.size() > 0) {
+                mScanStatus = SCANSTATUS_SUCCESS;
+            } else {
+                mScanStatus = SCANSTATUS_EMPTY;
+            }
         } catch (FileNotFoundException e) {
             e.printStackTrace();
+            mScanStatus = SCANSTATUS_FAIL;
         } catch (IOException e) {
             e.printStackTrace();
+            mScanStatus = SCANSTATUS_FAIL;
         }
-        return false;
+        if (DEBUG) {
+            Slog.i(TAG, "  status:" + mScanStatus);
+        }
+        return mScanStatus;
+    }
+
+    public int getScanStatus() {
+        return mScanStatus;
     }
 
     //
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
index d64c9a1..4a181b2 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -20,6 +20,7 @@
 import android.app.NotificationManager;
 import android.content.Context;
 import android.content.pm.ParceledListSlice;
+import android.media.AudioAttributes;
 import android.os.RemoteException;
 import android.provider.Settings;
 
@@ -47,6 +48,7 @@
     public static String RETAIL_MODE = "RETAIL_MODE";
     public static String USB = "USB";
     public static String FOREGROUND_SERVICE = "FOREGROUND_SERVICE";
+    public static String HEAVY_WEIGHT_APP = "HEAVY_WEIGHT_APP";
 
     public static void createAll(Context context) {
         final NotificationManager nm = context.getSystemService(NotificationManager.class);
@@ -139,6 +141,17 @@
         foregroundChannel.setBlockableSystem(true);
         channelsList.add(foregroundChannel);
 
+        NotificationChannel heavyWeightChannel = new NotificationChannel(
+                HEAVY_WEIGHT_APP,
+                context.getString(R.string.notification_channel_heavy_weight_app),
+                NotificationManager.IMPORTANCE_DEFAULT);
+        heavyWeightChannel.setShowBadge(false);
+        heavyWeightChannel.setSound(null, new AudioAttributes.Builder()
+                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+                .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT)
+                .build());
+        channelsList.add(heavyWeightChannel);
+
         nm.createNotificationChannels(channelsList);
     }
 
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index dc062f3..5c310b1 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -681,17 +681,17 @@
     }
 
     @Override
-    public long getMahDischarge(int which) {
+    public long getUahDischarge(int which) {
         return mDischargeCounter.getCountLocked(which);
     }
 
     @Override
-    public long getMahDischargeScreenOff(int which) {
+    public long getUahDischargeScreenOff(int which) {
         return mDischargeScreenOffCounter.getCountLocked(which);
     }
 
     @Override
-    public long getMahDischargeScreenDoze(int which) {
+    public long getUahDischargeScreenDoze(int which) {
         return mDischargeScreenDozeCounter.getCountLocked(which);
     }
 
@@ -3588,7 +3588,7 @@
 
     public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptime,
             long realtime) {
-        final boolean screenOff = isScreenOff(screenState) || isScreenDoze(screenState);
+        final boolean screenOff = !isScreenOn(screenState);
         final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning();
         final boolean updateOnBatteryScreenOffTimeBase =
                 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning();
@@ -5427,6 +5427,10 @@
                 elapsedRealtimeUs, which);
     }
 
+    @Override public Timer getScreenBrightnessTimer(int brightnessBin) {
+        return mScreenBrightnessTimer[brightnessBin];
+    }
+
     @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
         return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
     }
@@ -5520,10 +5524,18 @@
                 elapsedRealtimeUs, which);
     }
 
+    @Override public Timer getPhoneSignalScanningTimer() {
+        return mPhoneSignalScanningTimer;
+    }
+
     @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
         return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
     }
 
+    @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) {
+        return mPhoneSignalStrengthsTimer[strengthBin];
+    }
+
     @Override public long getPhoneDataConnectionTime(int dataType,
             long elapsedRealtimeUs, int which) {
         return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
@@ -5534,6 +5546,10 @@
         return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
     }
 
+    @Override public Timer getPhoneDataConnectionTimer(int dataType) {
+        return mPhoneDataConnectionsTimer[dataType];
+    }
+
     @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
         return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
     }
@@ -5572,6 +5588,10 @@
         return mWifiStateTimer[wifiState].getCountLocked(which);
     }
 
+    @Override public Timer getWifiStateTimer(int wifiState) {
+        return mWifiStateTimer[wifiState];
+    }
+
     @Override public long getWifiSupplStateTime(int state,
             long elapsedRealtimeUs, int which) {
         return mWifiSupplStateTimer[state].getTotalTimeLocked(
@@ -5582,6 +5602,10 @@
         return mWifiSupplStateTimer[state].getCountLocked(which);
     }
 
+    @Override public Timer getWifiSupplStateTimer(int state) {
+        return mWifiSupplStateTimer[state];
+    }
+
     @Override public long getWifiSignalStrengthTime(int strengthBin,
             long elapsedRealtimeUs, int which) {
         return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
@@ -5592,6 +5616,10 @@
         return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which);
     }
 
+    @Override public Timer getWifiSignalStrengthTimer(int strengthBin) {
+        return mWifiSignalStrengthsTimer[strengthBin];
+    }
+
     @Override
     public ControllerActivityCounter getBluetoothControllerActivity() {
         return mBluetoothActivity;
@@ -9463,7 +9491,7 @@
     }
 
     public boolean isScreenOn(int state) {
-        return state == Display.STATE_ON;
+        return state == Display.STATE_ON || state == Display.STATE_VR;
     }
 
     public boolean isScreenOff(int state) {
@@ -12791,7 +12819,7 @@
         mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
         mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null,
                 mOnBatteryTimeBase, in);
-        mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 
+        mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null,
                 mOnBatteryTimeBase, in);
         mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
         mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
diff --git a/core/java/com/android/internal/os/LoggingPrintStream.java b/core/java/com/android/internal/os/LoggingPrintStream.java
index f14394a..d27874c 100644
--- a/core/java/com/android/internal/os/LoggingPrintStream.java
+++ b/core/java/com/android/internal/os/LoggingPrintStream.java
@@ -28,12 +28,15 @@
 import java.util.Formatter;
 import java.util.Locale;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * A print stream which logs output line by line.
  *
  * {@hide}
  */
-abstract class LoggingPrintStream extends PrintStream {
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public abstract class LoggingPrintStream extends PrintStream {
 
     private final StringBuilder builder = new StringBuilder();
 
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 4abab28..2be6212 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -549,7 +549,7 @@
             try {
                 dexoptNeeded = DexFile.getDexOptNeeded(
                     classPathElement, instructionSet, systemServerFilter,
-                    false /* newProfile */, false /* downgrade */);
+                    null /* classLoaderContext */, false /* newProfile */, false /* downgrade */);
             } catch (FileNotFoundException ignored) {
                 // Do not add to the classpath.
                 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index b71fa06..8d71666 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -82,7 +82,7 @@
      * that are mapped in to processes.
      */
     public long getCachedSizeKb() {
-        return mInfos[Debug.MEMINFO_BUFFERS]
+        return mInfos[Debug.MEMINFO_BUFFERS] + mInfos[Debug.MEMINFO_SLAB_RECLAIMABLE]
                 + mInfos[Debug.MEMINFO_CACHED] - mInfos[Debug.MEMINFO_MAPPED];
     }
 
@@ -90,7 +90,7 @@
      * Amount of RAM that is in use by the kernel for actual allocations.
      */
     public long getKernelUsedSizeKb() {
-        return mInfos[Debug.MEMINFO_SHMEM] + mInfos[Debug.MEMINFO_SLAB]
+        return mInfos[Debug.MEMINFO_SHMEM] + mInfos[Debug.MEMINFO_SLAB_UNRECLAIMABLE]
                 + mInfos[Debug.MEMINFO_VM_ALLOC_USED] + mInfos[Debug.MEMINFO_PAGE_TABLES]
                 + mInfos[Debug.MEMINFO_KERNEL_STACK];
     }
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index f76c724..8f80bfe 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -319,13 +319,15 @@
     public void setGroupDividerEnabled(boolean groupDividerEnabled) {
         // If mHasListDivider is true, disabling the groupDivider.
         // Otherwise, checking enbling it according to groupDividerEnabled flag.
-        mGroupDivider.setVisibility(!mHasListDivider
-                && groupDividerEnabled ? View.VISIBLE : View.GONE);
+        if (mGroupDivider != null) {
+            mGroupDivider.setVisibility(!mHasListDivider
+                    && groupDividerEnabled ? View.VISIBLE : View.GONE);
+        }
     }
 
     @Override
     public void adjustListItemSelectionBounds(Rect rect) {
-        if (mGroupDivider.getVisibility() == View.VISIBLE) {
+        if (mGroupDivider != null && mGroupDivider.getVisibility() == View.VISIBLE) {
             // groupDivider is a part of MenuItemListView.
             // If ListMenuItem with divider enabled is hovered/clicked, divider also gets selected.
             // Clipping the selector bounds from the top divider portion when divider is enabled,
diff --git a/core/java/com/android/internal/widget/Magnifier.java b/core/java/com/android/internal/widget/Magnifier.java
index 86e7b38..284f2b2 100644
--- a/core/java/com/android/internal/widget/Magnifier.java
+++ b/core/java/com/android/internal/widget/Magnifier.java
@@ -41,6 +41,8 @@
  */
 public final class Magnifier {
     private static final String LOG_TAG = "magnifier";
+    private static final int MINIMUM_MAGNIFIER_SCALE = 1;
+    private static final int MAXIMUM_MAGNIFIER_SCALE = 4;
     // The view for which this magnifier is attached.
     private final View mView;
     // The window containing the magnifier.
@@ -94,7 +96,23 @@
      */
     public void show(@FloatRange(from=0) float centerXOnScreen,
             @FloatRange(from=0) float centerYOnScreen,
-            @FloatRange(from=1, to=10) float scale) {
+            @FloatRange(from=MINIMUM_MAGNIFIER_SCALE, to=MAXIMUM_MAGNIFIER_SCALE) float scale) {
+        if (scale > MAXIMUM_MAGNIFIER_SCALE) {
+            scale = MAXIMUM_MAGNIFIER_SCALE;
+        }
+
+        if (scale < MINIMUM_MAGNIFIER_SCALE) {
+            scale = MINIMUM_MAGNIFIER_SCALE;
+        }
+
+        if (centerXOnScreen < 0) {
+            centerXOnScreen = 0;
+        }
+
+        if (centerYOnScreen < 0) {
+            centerYOnScreen = 0;
+        }
+
         maybeResizeBitmap(scale);
         configureCoordinates(centerXOnScreen, centerYOnScreen);
         performPixelCopy();
@@ -144,12 +162,8 @@
 
         final int verticalMagnifierOffset = mView.getContext().getResources().getDimensionPixelSize(
                 R.dimen.magnifier_offset);
-        final int availableTopSpace = (mCenterZoomCoords.y - mWindowHeight / 2)
-                - verticalMagnifierOffset - (mBitmap.getHeight() / 2);
-
         mWindowCoords.x = mCenterZoomCoords.x - mWindowWidth / 2;
-        mWindowCoords.y = mCenterZoomCoords.y - mWindowHeight / 2
-                + verticalMagnifierOffset * (availableTopSpace > 0 ? -1 : 1);
+        mWindowCoords.y = mCenterZoomCoords.y - mWindowHeight / 2 - verticalMagnifierOffset;
     }
 
     private void performPixelCopy() {
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index deb4d5a..e312478 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -19,6 +19,8 @@
 #define LOG_NDEBUG 1
 
 #include <android_runtime/AndroidRuntime.h>
+
+#include <android-base/properties.h>
 #include <binder/IBinder.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -47,8 +49,8 @@
 #include <string>
 #include <vector>
 
-
 using namespace android;
+using android::base::GetProperty;
 
 extern int register_android_os_Binder(JNIEnv* env);
 extern int register_android_os_Process(JNIEnv* env);
@@ -392,17 +394,6 @@
     return false;
 }
 
-// Convenience wrapper over the property API that returns an
-// std::string.
-std::string getProperty(const char* key, const char* defaultValue) {
-    std::vector<char> temp(PROPERTY_VALUE_MAX);
-    const int len = property_get(key, &temp[0], defaultValue);
-    if (len < 0) {
-        return "";
-    }
-    return std::string(&temp[0], len);
-}
-
 /*
  * Read the persistent locale. Inspects the following system properties
  * (in order) and returns the first non-empty property in the list :
@@ -419,15 +410,15 @@
  */
 const std::string readLocale()
 {
-    const std::string locale = getProperty("persist.sys.locale", "");
+    const std::string locale = GetProperty("persist.sys.locale", "");
     if (!locale.empty()) {
         return locale;
     }
 
-    const std::string language = getProperty("persist.sys.language", "");
+    const std::string language = GetProperty("persist.sys.language", "");
     if (!language.empty()) {
-        const std::string country = getProperty("persist.sys.country", "");
-        const std::string variant = getProperty("persist.sys.localevar", "");
+        const std::string country = GetProperty("persist.sys.country", "");
+        const std::string variant = GetProperty("persist.sys.localevar", "");
 
         std::string out = language;
         if (!country.empty()) {
@@ -441,15 +432,15 @@
         return out;
     }
 
-    const std::string productLocale = getProperty("ro.product.locale", "");
+    const std::string productLocale = GetProperty("ro.product.locale", "");
     if (!productLocale.empty()) {
         return productLocale;
     }
 
     // If persist.sys.locale and ro.product.locale are missing,
     // construct a locale value from the individual locale components.
-    const std::string productLanguage = getProperty("ro.product.locale.language", "en");
-    const std::string productRegion = getProperty("ro.product.locale.region", "US");
+    const std::string productLanguage = GetProperty("ro.product.locale.language", "en");
+    const std::string productRegion = GetProperty("ro.product.locale.region", "US");
 
     return productLanguage + "-" + productRegion;
 }
@@ -617,6 +608,7 @@
     char jitprithreadweightOptBuf[sizeof("-Xjitprithreadweight:")-1 + PROPERTY_VALUE_MAX];
     char jittransitionweightOptBuf[sizeof("-Xjittransitionweight:")-1 + PROPERTY_VALUE_MAX];
     char hotstartupsamplesOptsBuf[sizeof("-Xps-hot-startup-method-samples:")-1 + PROPERTY_VALUE_MAX];
+    char madviseRandomOptsBuf[sizeof("-XX:MadviseRandomAccess:")-1 + PROPERTY_VALUE_MAX];
     char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];
     char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX];
     char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
@@ -649,7 +641,7 @@
     char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];
     char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX];
     char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX];
-    char fingerprintBuf[sizeof("-Xfingerprint:") + PROPERTY_VALUE_MAX];
+    std::string fingerprintBuf;
 
     bool checkJni = false;
     property_get("dalvik.vm.checkjni", propBuf, "");
@@ -744,6 +736,11 @@
                        "-Xjittransitionweight:");
 
     /*
+     * Madvise related options.
+     */
+    parseRuntimeOption("dalvik.vm.madvise-random", madviseRandomOptsBuf, "-XX:MadviseRandomAccess:");
+
+    /*
      * Profile related options.
      */
     parseRuntimeOption("dalvik.vm.hot-startup-method-samples", hotstartupsamplesOptsBuf,
@@ -964,8 +961,15 @@
     /*
      * Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will
      * contain the fingerprint and can be parsed.
+     * Fingerprints are potentially longer than PROPERTY_VALUE_MAX, so parseRuntimeOption() cannot
+     * be used here.
+     * Do not ever re-assign fingerprintBuf as its c_str() value is stored in mOptions.
      */
-    parseRuntimeOption("ro.build.fingerprint", fingerprintBuf, "-Xfingerprint:");
+    std::string fingerprint = GetProperty("ro.build.fingerprint", "");
+    if (!fingerprint.empty()) {
+        fingerprintBuf = "-Xfingerprint:" + fingerprint;
+        addOption(fingerprintBuf.c_str());
+    }
 
     initArgs.version = JNI_VERSION_1_4;
     initArgs.options = mOptions.editArray();
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index ad05a51..5498a93 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -682,6 +682,8 @@
 
     sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap);
     if (!nativeBitmap) {
+        ALOGE("OOM allocating Bitmap with dimensions %i x %i", width, height);
+        doThrowOOME(env);
         return NULL;
     }
 
@@ -1051,7 +1053,7 @@
     }
 
     // Read the bitmap blob.
-    size_t size = bitmap->getSize();
+    size_t size = bitmap->computeByteSize();
     android::Parcel::ReadableBlob blob;
     android::status_t status = p->readBlob(size, &blob);
     if (status) {
@@ -1188,7 +1190,7 @@
             p->allowFds() ? "allowed" : "forbidden");
 #endif
 
-    size_t size = bitmap.getSize();
+    size_t size = bitmap.computeByteSize();
     android::Parcel::WritableBlob blob;
     status = p->writeBlob(size, mutableCopy, &blob);
     if (status) {
@@ -1411,7 +1413,7 @@
         android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE);
 
         // the java side has already checked that buffer is large enough
-        memcpy(abp.pointer(), src, bitmap.getSize());
+        memcpy(abp.pointer(), src, bitmap.computeByteSize());
     }
 }
 
@@ -1424,7 +1426,7 @@
     if (NULL != dst) {
         android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE);
         // the java side has already checked that buffer is large enough
-        memcpy(dst, abp.pointer(), bitmap.getSize());
+        memcpy(dst, abp.pointer(), bitmap.computeByteSize());
         bitmap.notifyPixelsChanged();
     }
 }
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 64e12b4..5990d7b 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -174,13 +174,12 @@
             return false;
         }
 
-        const int64_t size64 = info.getSafeSize64(bitmap->rowBytes());
-        if (!sk_64_isS32(size64)) {
+        const size_t size = info.computeByteSize(bitmap->rowBytes());
+        if (size > SK_MaxS32) {
             ALOGW("bitmap is too large");
             return false;
         }
 
-        const size_t size = sk_64_asS32(size64);
         if (size > mSize) {
             ALOGW("bitmap marked for reuse (%u bytes) can't fit new bitmap "
                   "(%zu bytes)", mSize, size);
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 5ea501e..90cc7bb 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -645,7 +645,7 @@
     const int maxHeight = SkTMax(bitmap->height(), mRecycledBitmap->info().height());
     const SkImageInfo maxInfo = bitmap->info().makeWH(maxWidth, maxHeight);
     const size_t rowBytes = maxInfo.minRowBytes();
-    const size_t bytesNeeded = maxInfo.getSafeSize(rowBytes);
+    const size_t bytesNeeded = maxInfo.computeByteSize(rowBytes);
     if (bytesNeeded <= mRecycledBytes) {
         // Here we take advantage of reconfigure() to reset the rowBytes
         // of mRecycledBitmap.  It is very important that we pass in
diff --git a/core/jni/android_app_admin_SecurityLog.cpp b/core/jni/android_app_admin_SecurityLog.cpp
index 5c45b4b..b3bcaa0 100644
--- a/core/jni/android_app_admin_SecurityLog.cpp
+++ b/core/jni/android_app_admin_SecurityLog.cpp
@@ -14,183 +14,26 @@
  * limitations under the License.
  */
 
-#include <fcntl.h>
-
-#include <nativehelper/JNIHelp.h>
-#include "core_jni_helpers.h"
-#include "jni.h"
+#include <log/log_id.h>
 #include <private/android_logger.h>
 
-// The size of the tag number comes out of the payload size.
-#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+
+#include "core_jni_helpers.h"
+#include "eventlog_helper.h"
 
 namespace android {
 
-static jclass gCollectionClass;
-static jmethodID gCollectionAddID;
-
-static jclass gEventClass;
-static jmethodID gEventInitID;
-
-static jclass gIntegerClass;
-static jfieldID gIntegerValueID;
-
-static jclass gLongClass;
-static jfieldID gLongValueID;
-
-static jclass gFloatClass;
-static jfieldID gFloatValueID;
-
-static jclass gStringClass;
-
+constexpr char kSecurityLogEventClass[] = "android/app/admin/SecurityLog$SecurityEvent";
+template class EventLogHelper<log_id_t::LOG_ID_SECURITY, kSecurityLogEventClass>;
+using SLog = EventLogHelper<log_id_t::LOG_ID_SECURITY, kSecurityLogEventClass>;
 
 static jboolean android_app_admin_SecurityLog_isLoggingEnabled(JNIEnv* env,
                                                     jobject /* clazz */) {
     return (bool)__android_log_security();
 }
 
-static jint android_app_admin_SecurityLog_writeEvent_String(JNIEnv* env,
-                                                    jobject /* clazz */,
-                                                    jint tag, jstring value) {
-    uint8_t buf[MAX_EVENT_PAYLOAD];
-
-    // Don't throw NPE -- I feel like it's sort of mean for a logging function
-    // to be all crashy if you pass in NULL -- but make the NULL value explicit.
-    const char *str = value != NULL ? env->GetStringUTFChars(value, NULL) : "NULL";
-    uint32_t len = strlen(str);
-    size_t max = sizeof(buf) - sizeof(len) - 2;  // Type byte, final newline
-    if (len > max) len = max;
-
-    buf[0] = EVENT_TYPE_STRING;
-    memcpy(&buf[1], &len, sizeof(len));
-    memcpy(&buf[1 + sizeof(len)], str, len);
-    buf[1 + sizeof(len) + len] = '\n';
-
-    if (value != NULL) env->ReleaseStringUTFChars(value, str);
-    return __android_log_security_bwrite(tag, buf, 2 + sizeof(len) + len);
-}
-
-static jint android_app_admin_SecurityLog_writeEvent_Array(JNIEnv* env, jobject clazz,
-                                                   jint tag, jobjectArray value) {
-    if (value == NULL) {
-        return android_app_admin_SecurityLog_writeEvent_String(env, clazz, tag, NULL);
-    }
-
-    uint8_t buf[MAX_EVENT_PAYLOAD];
-    const size_t max = sizeof(buf) - 1;  // leave room for final newline
-    size_t pos = 2;  // Save room for type tag & array count
-
-    jsize copied = 0, num = env->GetArrayLength(value);
-    for (; copied < num && copied < 255; ++copied) {
-        jobject item = env->GetObjectArrayElement(value, copied);
-        if (item == NULL || env->IsInstanceOf(item, gStringClass)) {
-            if (pos + 1 + sizeof(jint) > max) break;
-            const char *str = item != NULL ? env->GetStringUTFChars((jstring) item, NULL) : "NULL";
-            jint len = strlen(str);
-            if (pos + 1 + sizeof(len) + len > max) len = max - pos - 1 - sizeof(len);
-            buf[pos++] = EVENT_TYPE_STRING;
-            memcpy(&buf[pos], &len, sizeof(len));
-            memcpy(&buf[pos + sizeof(len)], str, len);
-            pos += sizeof(len) + len;
-            if (item != NULL) env->ReleaseStringUTFChars((jstring) item, str);
-        } else if (env->IsInstanceOf(item, gIntegerClass)) {
-            jint intVal = env->GetIntField(item, gIntegerValueID);
-            if (pos + 1 + sizeof(intVal) > max) break;
-            buf[pos++] = EVENT_TYPE_INT;
-            memcpy(&buf[pos], &intVal, sizeof(intVal));
-            pos += sizeof(intVal);
-        } else if (env->IsInstanceOf(item, gLongClass)) {
-            jlong longVal = env->GetLongField(item, gLongValueID);
-            if (pos + 1 + sizeof(longVal) > max) break;
-            buf[pos++] = EVENT_TYPE_LONG;
-            memcpy(&buf[pos], &longVal, sizeof(longVal));
-            pos += sizeof(longVal);
-        } else if (env->IsInstanceOf(item, gFloatClass)) {
-            jfloat floatVal = env->GetFloatField(item, gFloatValueID);
-            if (pos + 1 + sizeof(floatVal) > max) break;
-            buf[pos++] = EVENT_TYPE_FLOAT;
-            memcpy(&buf[pos], &floatVal, sizeof(floatVal));
-            pos += sizeof(floatVal);
-        } else {
-            jniThrowException(env,
-                    "java/lang/IllegalArgumentException",
-                    "Invalid payload item type");
-            return -1;
-        }
-        env->DeleteLocalRef(item);
-    }
-
-    buf[0] = EVENT_TYPE_LIST;
-    buf[1] = copied;
-    buf[pos++] = '\n';
-    return __android_log_security_bwrite(tag, buf, pos);
-}
-
-static void readEvents(JNIEnv* env, int loggerMode, jlong startTime, jobject out) {
-    struct logger_list *logger_list;
-    if (startTime) {
-        logger_list = android_logger_list_alloc_time(loggerMode,
-                log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0);
-    } else {
-        logger_list = android_logger_list_alloc(loggerMode, 0, 0);
-    }
-    if (!logger_list) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-
-    if (!android_logger_open(logger_list, LOG_ID_SECURITY)) {
-        jniThrowIOException(env, errno);
-        android_logger_list_free(logger_list);
-        return;
-    }
-
-    while (1) {
-        log_msg log_msg;
-        int ret = android_logger_list_read(logger_list, &log_msg);
-
-        if (ret == 0) {
-            break;
-        }
-        if (ret < 0) {
-            if (ret == -EINTR) {
-                continue;
-            }
-            if (ret == -EINVAL) {
-                jniThrowException(env, "java/io/IOException", "Event too short");
-            } else if (ret != -EAGAIN) {
-                jniThrowIOException(env, -ret);  // Will throw on return
-            }
-            break;
-        }
-
-        if (log_msg.id() != LOG_ID_SECURITY) {
-            continue;
-        }
-
-        jsize len = ret;
-        jbyteArray array = env->NewByteArray(len);
-        if (array == NULL) {
-            break;
-        }
-
-        jbyte *bytes = env->GetByteArrayElements(array, NULL);
-        memcpy(bytes, log_msg.buf, len);
-        env->ReleaseByteArrayElements(array, bytes, 0);
-
-        jobject event = env->NewObject(gEventClass, gEventInitID, array);
-        if (event == NULL) {
-            break;
-        }
-
-        env->CallBooleanMethod(out, gCollectionAddID, event);
-        env->DeleteLocalRef(event);
-        env->DeleteLocalRef(array);
-    }
-
-    android_logger_list_close(logger_list);
-}
-
 static void android_app_admin_SecurityLog_readEvents(JNIEnv* env, jobject /* clazz */,
                                              jobject out) {
 
@@ -198,7 +41,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out);
+    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out);
 }
 
 static void android_app_admin_SecurityLog_readEventsSince(JNIEnv* env, jobject /* clazz */,
@@ -209,7 +52,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out);
+    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out);
 }
 
 static void android_app_admin_SecurityLog_readPreviousEvents(JNIEnv* env, jobject /* clazz */,
@@ -219,7 +62,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out);
+    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out);
 }
 
 static void android_app_admin_SecurityLog_readEventsOnWrapping(JNIEnv* env, jobject /* clazz */,
@@ -229,7 +72,8 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp, out);
+    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp,
+            out);
 }
 
 /*
@@ -243,11 +87,11 @@
     },
     { "writeEvent",
       "(ILjava/lang/String;)I",
-      (void*) android_app_admin_SecurityLog_writeEvent_String
+      (void*) SLog::writeEventString
     },
     { "writeEvent",
       "(I[Ljava/lang/Object;)I",
-      (void*) android_app_admin_SecurityLog_writeEvent_Array
+      (void*) SLog::writeEventArray
     },
     { "readEvents",
       "(Ljava/util/Collection;)V",
@@ -267,41 +111,8 @@
     },
 };
 
-static struct { const char *name; jclass *clazz; } gClasses[] = {
-    { "android/app/admin/SecurityLog$SecurityEvent", &gEventClass },
-    { "java/lang/Integer", &gIntegerClass },
-    { "java/lang/Long", &gLongClass },
-    { "java/lang/Float", &gFloatClass },
-    { "java/lang/String", &gStringClass },
-    { "java/util/Collection", &gCollectionClass },
-};
-
-static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
-    { &gIntegerClass, "value", "I", &gIntegerValueID },
-    { &gLongClass, "value", "J", &gLongValueID },
-    { &gFloatClass, "value", "F", &gFloatValueID },
-};
-
-static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
-    { &gEventClass, "<init>", "([B)V", &gEventInitID },
-    { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID },
-};
-
 int register_android_app_admin_SecurityLog(JNIEnv* env) {
-    for (int i = 0; i < NELEM(gClasses); ++i) {
-        jclass clazz = FindClassOrDie(env, gClasses[i].name);
-        *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz);
-    }
-
-    for (int i = 0; i < NELEM(gFields); ++i) {
-        *gFields[i].id = GetFieldIDOrDie(env,
-                *gFields[i].c, gFields[i].name, gFields[i].ft);
-    }
-
-    for (int i = 0; i < NELEM(gMethods); ++i) {
-        *gMethods[i].id = GetMethodIDOrDie(env,
-                *gMethods[i].c, gMethods[i].name, gMethods[i].mt);
-    }
+    SLog::Init(env);
 
     return RegisterMethodsOrDie(
             env,
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index c8eef7f..1628220 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -23,13 +23,13 @@
 #include <vector>
 #include <cmath>
 
+#include <android-base/properties.h>
 #include <utils/Log.h>
 #include <utils/Errors.h>
 #include <utils/StrongPointer.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
 #include <utils/String8.h>
-#include <cutils/properties.h>
 #include <system/camera_metadata.h>
 #include <camera/CameraMetadata.h>
 #include <img_utils/DngUtils.h>
@@ -50,6 +50,7 @@
 
 using namespace android;
 using namespace img_utils;
+using android::base::GetProperty;
 
 #define BAIL_IF_INVALID_RET_BOOL(expr, jnienv, tagId, writer) \
     if ((expr) != OK) { \
@@ -1237,26 +1238,24 @@
 
     {
         // make
-        char manufacturer[PROPERTY_VALUE_MAX];
-
         // Use "" to represent unknown make as suggested in TIFF/EP spec.
-        property_get("ro.product.manufacturer", manufacturer, "");
-        uint32_t count = static_cast<uint32_t>(strlen(manufacturer)) + 1;
+        std::string manufacturer = GetProperty("ro.product.manufacturer", "");
+        uint32_t count = static_cast<uint32_t>(manufacturer.size()) + 1;
 
         BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_MAKE, count,
-                reinterpret_cast<uint8_t*>(manufacturer), TIFF_IFD_0), env, TAG_MAKE, writer);
+                reinterpret_cast<const uint8_t*>(manufacturer.c_str()), TIFF_IFD_0), env, TAG_MAKE,
+                writer);
     }
 
     {
         // model
-        char model[PROPERTY_VALUE_MAX];
-
         // Use "" to represent unknown model as suggested in TIFF/EP spec.
-        property_get("ro.product.model", model, "");
-        uint32_t count = static_cast<uint32_t>(strlen(model)) + 1;
+        std::string model = GetProperty("ro.product.model", "");
+        uint32_t count = static_cast<uint32_t>(model.size()) + 1;
 
         BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_MODEL, count,
-                reinterpret_cast<uint8_t*>(model), TIFF_IFD_0), env, TAG_MODEL, writer);
+                reinterpret_cast<const uint8_t*>(model.c_str()), TIFF_IFD_0), env, TAG_MODEL,
+                writer);
     }
 
     {
@@ -1277,11 +1276,11 @@
 
     {
         // software
-        char software[PROPERTY_VALUE_MAX];
-        property_get("ro.build.fingerprint", software, "");
-        uint32_t count = static_cast<uint32_t>(strlen(software)) + 1;
+        std::string software = GetProperty("ro.build.fingerprint", "");
+        uint32_t count = static_cast<uint32_t>(software.size()) + 1;
         BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_SOFTWARE, count,
-                reinterpret_cast<uint8_t*>(software), TIFF_IFD_0), env, TAG_SOFTWARE, writer);
+                reinterpret_cast<const uint8_t*>(software.c_str()), TIFF_IFD_0), env, TAG_SOFTWARE,
+                writer);
     }
 
     if (nativeContext->hasCaptureTime()) {
@@ -1613,20 +1612,15 @@
 
     {
         // Setup unique camera model tag
-        char model[PROPERTY_VALUE_MAX];
-        property_get("ro.product.model", model, "");
+        std::string model = GetProperty("ro.product.model", "");
+        std::string manufacturer = GetProperty("ro.product.manufacturer", "");
+        std::string brand = GetProperty("ro.product.brand", "");
 
-        char manufacturer[PROPERTY_VALUE_MAX];
-        property_get("ro.product.manufacturer", manufacturer, "");
-
-        char brand[PROPERTY_VALUE_MAX];
-        property_get("ro.product.brand", brand, "");
-
-        String8 cameraModel(model);
+        String8 cameraModel(model.c_str());
         cameraModel += "-";
-        cameraModel += manufacturer;
+        cameraModel += manufacturer.c_str();
         cameraModel += "-";
-        cameraModel += brand;
+        cameraModel += brand.c_str();
 
         BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_UNIQUECAMERAMODEL, cameraModel.size() + 1,
                 reinterpret_cast<const uint8_t*>(cameraModel.string()), TIFF_IFD_0), env,
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index a140b57..e33d6ea 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -705,6 +705,8 @@
     MEMINFO_CACHED,
     MEMINFO_SHMEM,
     MEMINFO_SLAB,
+    MEMINFO_SLAB_RECLAIMABLE,
+    MEMINFO_SLAB_UNRECLAIMABLE,
     MEMINFO_SWAP_TOTAL,
     MEMINFO_SWAP_FREE,
     MEMINFO_ZRAM_TOTAL,
@@ -776,6 +778,8 @@
             "Cached:",
             "Shmem:",
             "Slab:",
+            "SReclaimable:",
+            "SUnreclaim:",
             "SwapTotal:",
             "SwapFree:",
             "ZRam:",
@@ -792,6 +796,8 @@
             7,
             6,
             5,
+            13,
+            11,
             10,
             9,
             5,
@@ -801,7 +807,7 @@
             12,
             0
     };
-    long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+    long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
     char* p = buffer;
     while (*p && numFound < (sizeof(tagsLen) / sizeof(tagsLen[0]))) {
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 83ffeff..1f7277a 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -166,7 +166,7 @@
                                jobject recycle, jintArray recycleBreaks,
                                jfloatArray recycleWidths, jfloatArray recycleAscents,
                                jfloatArray recycleDescents, jintArray recycleFlags,
-                               jint recycleLength) {
+                               jint recycleLength, jfloatArray charWidths) {
     minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
 
     size_t nBreaks = b->computeBreaks();
@@ -175,6 +175,8 @@
             recycleFlags, recycleLength, nBreaks, b->getBreaks(), b->getWidths(), b->getAscents(),
             b->getDescents(), b->getFlags());
 
+    env->SetFloatArrayRegion(charWidths, 0, b->size(), b->charWidths());
+
     b->finish();
 
     return static_cast<jint>(nBreaks);
@@ -256,11 +258,6 @@
     b->addReplacement(start, end, width, langTagsString.get(), makeHyphenators(env, hyphenators));
 }
 
-static void nGetWidths(JNIEnv* env, jclass, jlong nativePtr, jfloatArray widths) {
-    minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
-    env->SetFloatArrayRegion(widths, 0, b->size(), b->charWidths());
-}
-
 static const JNINativeMethod gMethods[] = {
     // TODO performance: many of these are candidates for fast jni, awaiting guidance
     {"nNewBuilder", "()J", (void*) nNewBuilder},
@@ -269,8 +266,7 @@
     {"nSetupParagraph", "(J[CIFIF[IIIIZ[I[I[II)V", (void*) nSetupParagraph},
     {"nAddStyleRun", "(JJIIZLjava/lang/String;[J)V", (void*) nAddStyleRun},
     {"nAddReplacementRun", "(JIIFLjava/lang/String;[J)V", (void*) nAddReplacementRun},
-    {"nGetWidths", "(J[F)V", (void*) nGetWidths},
-    {"nComputeLineBreaks", "(JLandroid/text/StaticLayout$LineBreaks;[I[F[F[F[II)I",
+    {"nComputeLineBreaks", "(JLandroid/text/StaticLayout$LineBreaks;[I[F[F[F[II[F)I",
         (void*) nComputeLineBreaks}
 };
 
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 9fd7c40..3b5a144 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -14,214 +14,20 @@
  * limitations under the License.
  */
 
-#include <fcntl.h>
-
-#include <log/log_event_list.h>
-
-#include <log/log.h>
+#include <android-base/macros.h>
+#include <log/log_id.h>
 
 #include <nativehelper/JNIHelp.h>
-#include "core_jni_helpers.h"
 #include "jni.h"
 
-#define UNUSED  __attribute__((__unused__))
+#include "core_jni_helpers.h"
+#include "eventlog_helper.h"
 
 namespace android {
 
-static jclass gCollectionClass;
-static jmethodID gCollectionAddID;
-
-static jclass gEventClass;
-static jmethodID gEventInitID;
-
-static jclass gIntegerClass;
-static jfieldID gIntegerValueID;
-
-static jclass gLongClass;
-static jfieldID gLongValueID;
-
-static jclass gFloatClass;
-static jfieldID gFloatValueID;
-
-static jclass gStringClass;
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(int tag, int value)
- */
-static jint android_util_EventLog_writeEvent_Integer(JNIEnv* env UNUSED,
-                                                     jobject clazz UNUSED,
-                                                     jint tag, jint value)
-{
-    android_log_event_list ctx(tag);
-    ctx << (int32_t)value;
-    return ctx.write();
-}
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(long tag, long value)
- */
-static jint android_util_EventLog_writeEvent_Long(JNIEnv* env UNUSED,
-                                                  jobject clazz UNUSED,
-                                                  jint tag, jlong value)
-{
-    android_log_event_list ctx(tag);
-    ctx << (int64_t)value;
-    return ctx.write();
-}
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(long tag, float value)
- */
-static jint android_util_EventLog_writeEvent_Float(JNIEnv* env UNUSED,
-                                                  jobject clazz UNUSED,
-                                                  jint tag, jfloat value)
-{
-    android_log_event_list ctx(tag);
-    ctx << (float)value;
-    return ctx.write();
-}
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(int tag, String value)
- */
-static jint android_util_EventLog_writeEvent_String(JNIEnv* env,
-                                                    jobject clazz UNUSED,
-                                                    jint tag, jstring value) {
-    android_log_event_list ctx(tag);
-    // Don't throw NPE -- I feel like it's sort of mean for a logging function
-    // to be all crashy if you pass in NULL -- but make the NULL value explicit.
-    if (value != NULL) {
-        const char *str = env->GetStringUTFChars(value, NULL);
-        ctx << str;
-        env->ReleaseStringUTFChars(value, str);
-    } else {
-        ctx << "NULL";
-    }
-    return ctx.write();
-}
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(long tag, Object... value)
- */
-static jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz,
-                                                   jint tag, jobjectArray value) {
-    android_log_event_list ctx(tag);
-
-    if (value == NULL) {
-        ctx << "[NULL]";
-        return ctx.write();
-    }
-
-    jsize copied = 0, num = env->GetArrayLength(value);
-    for (; copied < num && copied < 255; ++copied) {
-        if (ctx.status()) break;
-        jobject item = env->GetObjectArrayElement(value, copied);
-        if (item == NULL) {
-            ctx << "NULL";
-        } else if (env->IsInstanceOf(item, gStringClass)) {
-            const char *str = env->GetStringUTFChars((jstring) item, NULL);
-            ctx << str;
-            env->ReleaseStringUTFChars((jstring) item, str);
-        } else if (env->IsInstanceOf(item, gIntegerClass)) {
-            ctx << (int32_t)env->GetIntField(item, gIntegerValueID);
-        } else if (env->IsInstanceOf(item, gLongClass)) {
-            ctx << (int64_t)env->GetLongField(item, gLongValueID);
-        } else if (env->IsInstanceOf(item, gFloatClass)) {
-            ctx << (float)env->GetFloatField(item, gFloatValueID);
-        } else {
-            jniThrowException(env,
-                    "java/lang/IllegalArgumentException",
-                    "Invalid payload item type");
-            return -1;
-        }
-        env->DeleteLocalRef(item);
-    }
-    return ctx.write();
-}
-
-static void readEvents(JNIEnv* env, int loggerMode, jintArray tags, jlong startTime, jobject out) {
-    struct logger_list *logger_list;
-    if (startTime) {
-        logger_list = android_logger_list_alloc_time(loggerMode,
-                log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0);
-    } else {
-        logger_list = android_logger_list_alloc(loggerMode, 0, 0);
-    }
-    if (!logger_list) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-
-    if (!android_logger_open(logger_list, LOG_ID_EVENTS)) {
-        jniThrowIOException(env, errno);
-        android_logger_list_free(logger_list);
-        return;
-    }
-
-    jsize tagLength = env->GetArrayLength(tags);
-    jint *tagValues = env->GetIntArrayElements(tags, NULL);
-
-    while (1) {
-        log_msg log_msg;
-        int ret = android_logger_list_read(logger_list, &log_msg);
-
-        if (ret == 0) {
-            break;
-        }
-        if (ret < 0) {
-            if (ret == -EINTR) {
-                continue;
-            }
-            if (ret == -EINVAL) {
-                jniThrowException(env, "java/io/IOException", "Event too short");
-            } else if (ret != -EAGAIN) {
-                jniThrowIOException(env, -ret);  // Will throw on return
-            }
-            break;
-        }
-
-        if (log_msg.id() != LOG_ID_EVENTS) {
-            continue;
-        }
-
-        int32_t tag = * (int32_t *) log_msg.msg();
-
-        int found = 0;
-        for (int i = 0; !found && i < tagLength; ++i) {
-            found = (tag == tagValues[i]);
-        }
-
-        if (found) {
-            jsize len = ret;
-            jbyteArray array = env->NewByteArray(len);
-            if (array == NULL) {
-                break;
-            }
-
-            jbyte *bytes = env->GetByteArrayElements(array, NULL);
-            memcpy(bytes, log_msg.buf, len);
-            env->ReleaseByteArrayElements(array, bytes, 0);
-
-            jobject event = env->NewObject(gEventClass, gEventInitID, array);
-            if (event == NULL) {
-                break;
-            }
-
-            env->CallBooleanMethod(out, gCollectionAddID, event);
-            env->DeleteLocalRef(event);
-            env->DeleteLocalRef(array);
-        }
-    }
-
-    android_logger_list_close(logger_list);
-
-    env->ReleaseIntArrayElements(tags, tagValues, 0);
-}
+constexpr char kEventLogEventClass[] = "android/util/EventLog$Event";
+template class EventLogHelper<log_id_t::LOG_ID_EVENTS, kEventLogEventClass>;
+using ELog = EventLogHelper<log_id_t::LOG_ID_EVENTS, kEventLogEventClass>;
 
 /*
  * In class android.util.EventLog:
@@ -229,7 +35,7 @@
  *
  *  Reads events from the event log
  */
-static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz UNUSED,
+static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED,
                                              jintArray tags,
                                              jobject out) {
 
@@ -238,7 +44,7 @@
         return;
     }
 
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tags, 0, out);
+    ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tags, 0, out);
  }
 /*
  * In class android.util.EventLog:
@@ -246,7 +52,7 @@
  *
  *  Reads events from the event log, blocking until events after timestamp are to be overwritten.
  */
-static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject clazz UNUSED,
+static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED,
                                              jintArray tags,
                                              jlong timestamp,
                                              jobject out) {
@@ -254,8 +60,8 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP,
-            tags, timestamp, out);
+    ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, tags,
+            timestamp, out);
 }
 
 /*
@@ -263,17 +69,11 @@
  */
 static const JNINativeMethod gRegisterMethods[] = {
     /* name, signature, funcPtr */
-    { "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer },
-    { "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long },
-    { "writeEvent", "(IF)I", (void*) android_util_EventLog_writeEvent_Float },
-    { "writeEvent",
-      "(ILjava/lang/String;)I",
-      (void*) android_util_EventLog_writeEvent_String
-    },
-    { "writeEvent",
-      "(I[Ljava/lang/Object;)I",
-      (void*) android_util_EventLog_writeEvent_Array
-    },
+    { "writeEvent", "(II)I", (void*) ELog::writeEventInteger },
+    { "writeEvent", "(IJ)I", (void*) ELog::writeEventLong },
+    { "writeEvent", "(IF)I", (void*) ELog::writeEventFloat },
+    { "writeEvent", "(ILjava/lang/String;)I", (void*) ELog::writeEventString },
+    { "writeEvent", "(I[Ljava/lang/Object;)I", (void*) ELog::writeEventArray },
     { "readEvents",
       "([ILjava/util/Collection;)V",
       (void*) android_util_EventLog_readEvents
@@ -284,41 +84,8 @@
     },
 };
 
-static struct { const char *name; jclass *clazz; } gClasses[] = {
-    { "android/util/EventLog$Event", &gEventClass },
-    { "java/lang/Integer", &gIntegerClass },
-    { "java/lang/Long", &gLongClass },
-    { "java/lang/Float", &gFloatClass },
-    { "java/lang/String", &gStringClass },
-    { "java/util/Collection", &gCollectionClass },
-};
-
-static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
-    { &gIntegerClass, "value", "I", &gIntegerValueID },
-    { &gLongClass, "value", "J", &gLongValueID },
-    { &gFloatClass, "value", "F", &gFloatValueID },
-};
-
-static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
-    { &gEventClass, "<init>", "([B)V", &gEventInitID },
-    { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID },
-};
-
 int register_android_util_EventLog(JNIEnv* env) {
-    for (int i = 0; i < NELEM(gClasses); ++i) {
-        jclass clazz = FindClassOrDie(env, gClasses[i].name);
-        *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz);
-    }
-
-    for (int i = 0; i < NELEM(gFields); ++i) {
-        *gFields[i].id = GetFieldIDOrDie(env,
-                *gFields[i].c, gFields[i].name, gFields[i].ft);
-    }
-
-    for (int i = 0; i < NELEM(gMethods); ++i) {
-        *gMethods[i].id = GetMethodIDOrDie(env,
-                *gMethods[i].c, gMethods[i].name, gMethods[i].mt);
-    }
+    ELog::Init(env);
 
     return RegisterMethodsOrDie(
             env,
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index a9b849e..8ae9ada 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -98,6 +98,18 @@
 
 // ----------------------------------------------------------------------------
 
+static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
+    return reinterpret_cast<jlong>(new SurfaceComposerClient::Transaction);
+}
+
+static void releaseTransaction(SurfaceComposerClient::Transaction* t) {
+    delete t;
+}
+
+static jlong nativeGetNativeTransactionFinalizer(JNIEnv* env, jclass clazz) {
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseTransaction));
+}
+
 static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
         jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
         jint windowType, jint ownerUid) {
@@ -278,69 +290,72 @@
     }
 }
 
-static void nativeOpenTransaction(JNIEnv* env, jclass clazz) {
-    SurfaceComposerClient::openGlobalTransaction();
+static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->apply(sync);
 }
 
-
-static void nativeCloseTransaction(JNIEnv* env, jclass clazz, jboolean sync) {
-    SurfaceComposerClient::closeGlobalTransaction(sync);
+static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz, jlong transactionObj) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->setAnimationTransaction();
 }
 
-static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
-    SurfaceComposerClient::setAnimationTransaction();
-}
+static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jint zorder) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
 
-static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong nativeObject, jint zorder) {
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setLayer(zorder);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setLayer(ctrl, zorder);
 }
 
-static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jobject relativeTo, jint zorder) {
+
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<IBinder> handle = ibinderForJavaObject(env, relativeTo);
 
-    ctrl->setRelativeLayer(handle, zorder);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setRelativeLayer(ctrl, handle, zorder);
+    }
 }
 
-static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat x, jfloat y) {
+static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jfloat x, jfloat y) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setPosition(x, y);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setPosition(ctrl, x, y);
 }
 
 static void nativeSetGeometryAppliesWithResize(JNIEnv* env, jclass clazz,
+jlong transactionObj,
         jlong nativeObject) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setGeometryAppliesWithResize();
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setGeometryAppliesWithResize(ctrl);
 }
 
-static void nativeSetSize(JNIEnv* env, jclass clazz, jlong nativeObject, jint w, jint h) {
+static void nativeSetSize(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jint w, jint h) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setSize(w, h);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setSize(ctrl, w, h);
 }
 
-static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong nativeObject, jint flags, jint mask) {
+static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jint flags, jint mask) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setFlags(flags, mask);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setFlags(ctrl, flags, mask);
 }
 
-static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong nativeObject, jobject regionObj) {
+static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jobject regionObj) {
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
     if (!region) {
@@ -359,65 +374,65 @@
         }
     }
 
-    status_t err = ctrl->setTransparentRegionHint(reg);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setTransparentRegionHint(ctrl, reg);
     }
 }
 
-static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat alpha) {
+static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jfloat alpha) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setAlpha(alpha);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setAlpha(ctrl, alpha);
 }
 
-static void nativeSetColor(JNIEnv* env, jclass clazz, jlong nativeObject, jfloatArray fColor) {
+static void nativeSetColor(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jfloatArray fColor) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+
     float* floatColors = env->GetFloatArrayElements(fColor, 0);
     half3 color(floatColors[0], floatColors[1], floatColors[2]);
-    status_t err = ctrl->setColor(color);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setColor(ctrl, color);
 }
 
-static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jfloat dsdx, jfloat dtdx, jfloat dtdy, jfloat dsdy) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setMatrix(dsdx, dtdx, dtdy, dsdy);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setMatrix(ctrl, dsdx, dtdx, dtdy, dsdy);
 }
 
-static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jint l, jint t, jint r, jint b) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     Rect crop(l, t, r, b);
-    status_t err = ctrl->setCrop(crop);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setCrop(ctrl, crop);
 }
 
-static void nativeSetFinalCrop(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetFinalCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jint l, jint t, jint r, jint b) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     Rect crop(l, t, r, b);
-    status_t err = ctrl->setFinalCrop(crop);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setFinalCrop(ctrl, crop);
 }
 
-static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong nativeObject, jint layerStack) {
+static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jint layerStack) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setLayerStack(layerStack);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setLayerStack(ctrl, layerStack);
 }
 
 static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
@@ -440,6 +455,7 @@
 }
 
 static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
+        jlong transactionObj,
         jobject tokenObj, jlong nativeSurfaceObject) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
     if (token == NULL) return;
@@ -448,8 +464,14 @@
     if (sur != NULL) {
         bufferProducer = sur->getIGraphicBufferProducer();
     }
-    status_t err = SurfaceComposerClient::setDisplaySurface(token,
-            bufferProducer);
+
+
+    status_t err = NO_ERROR;
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        err = transaction->setDisplaySurface(token,
+                bufferProducer);
+    }
     if (err != NO_ERROR) {
         doThrowIAE(env, "Illegal Surface, could not enable async mode. Was this"
                 " Surface created with singleBufferMode?");
@@ -457,14 +479,20 @@
 }
 
 static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
+        jlong transactionObj,
         jobject tokenObj, jint layerStack) {
+
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
     if (token == NULL) return;
 
-    SurfaceComposerClient::setDisplayLayerStack(token, layerStack);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setDisplayLayerStack(token, layerStack);
+    }
 }
 
 static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
+        jlong transactionObj,
         jobject tokenObj, jint orientation,
         jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom,
         jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) {
@@ -472,14 +500,23 @@
     if (token == NULL) return;
     Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom);
     Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom);
-    SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect);
+
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setDisplayProjection(token, orientation, layerStackRect, displayRect);
+    }
 }
 
 static void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
+        jlong transactionObj,
         jobject tokenObj, jint width, jint height) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
     if (token == NULL) return;
-    SurfaceComposerClient::setDisplaySize(token, width, height);
+
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setDisplaySize(token, width, height);
+    }
 }
 
 static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz,
@@ -722,52 +759,73 @@
     return JNI_TRUE;
 }
 
-static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jobject handleObject, jlong frameNumber) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<IBinder> handle = ibinderForJavaObject(env, handleObject);
 
-    ctrl->deferTransactionUntil(handle, frameNumber);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->deferTransactionUntil(ctrl, handle, frameNumber);
+    }
 }
 
-static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jlong surfaceObject, jlong frameNumber) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject);
 
-    ctrl->deferTransactionUntil(barrier, frameNumber);
+    transaction->deferTransactionUntil(ctrl, barrier, frameNumber);
 }
 
-static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jobject newParentObject) {
+
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<IBinder> handle = ibinderForJavaObject(env, newParentObject);
 
-    ctrl->reparentChildren(handle);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->reparentChildren(ctrl, handle);
+    }
 }
 
-static void nativeReparent(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jobject newParentObject) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<IBinder> parentHandle = ibinderForJavaObject(env, newParentObject);
-    ctrl->reparent(parentHandle);
+
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->reparent(ctrl, parentHandle);
+    }
 }
 
-static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong nativeObject) {
+static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    ctrl->detachChildren();
+    transaction->detachChildren(ctrl);
 }
 
-static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jint scalingMode) {
-    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
 
-    ctrl->setOverrideScalingMode(scalingMode);
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    transaction->setOverrideScalingMode(ctrl, scalingMode);
 }
 
 static jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-
     return javaObjectForIBinder(env, ctrl->getHandle());
 }
 
@@ -802,37 +860,39 @@
             (void*)nativeScreenshotBitmap },
     {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
             (void*)nativeScreenshot },
-    {"nativeOpenTransaction", "()V",
-            (void*)nativeOpenTransaction },
-    {"nativeCloseTransaction", "(Z)V",
-            (void*)nativeCloseTransaction },
-    {"nativeSetAnimationTransaction", "()V",
+    {"nativeCreateTransaction", "()J",
+            (void*)nativeCreateTransaction },
+    {"nativeApplyTransaction", "(JZ)V",
+            (void*)nativeApplyTransaction },
+    {"nativeGetNativeTransactionFinalizer", "()J",
+            (void*)nativeGetNativeTransactionFinalizer },
+    {"nativeSetAnimationTransaction", "(J)V",
             (void*)nativeSetAnimationTransaction },
-    {"nativeSetLayer", "(JI)V",
+    {"nativeSetLayer", "(JJI)V",
             (void*)nativeSetLayer },
-    {"nativeSetRelativeLayer", "(JLandroid/os/IBinder;I)V",
+    {"nativeSetRelativeLayer", "(JJLandroid/os/IBinder;I)V",
             (void*)nativeSetRelativeLayer },
-    {"nativeSetPosition", "(JFF)V",
+    {"nativeSetPosition", "(JJFF)V",
             (void*)nativeSetPosition },
-    {"nativeSetGeometryAppliesWithResize", "(J)V",
+    {"nativeSetGeometryAppliesWithResize", "(JJ)V",
             (void*)nativeSetGeometryAppliesWithResize },
-    {"nativeSetSize", "(JII)V",
+    {"nativeSetSize", "(JJII)V",
             (void*)nativeSetSize },
-    {"nativeSetTransparentRegionHint", "(JLandroid/graphics/Region;)V",
+    {"nativeSetTransparentRegionHint", "(JJLandroid/graphics/Region;)V",
             (void*)nativeSetTransparentRegionHint },
-    {"nativeSetAlpha", "(JF)V",
+    {"nativeSetAlpha", "(JJF)V",
             (void*)nativeSetAlpha },
-    {"nativeSetColor", "(J[F)V",
+    {"nativeSetColor", "(JJ[F)V",
             (void*)nativeSetColor },
-    {"nativeSetMatrix", "(JFFFF)V",
+    {"nativeSetMatrix", "(JJFFFF)V",
             (void*)nativeSetMatrix },
-    {"nativeSetFlags", "(JII)V",
+    {"nativeSetFlags", "(JJII)V",
             (void*)nativeSetFlags },
-    {"nativeSetWindowCrop", "(JIIII)V",
+    {"nativeSetWindowCrop", "(JJIIII)V",
             (void*)nativeSetWindowCrop },
-    {"nativeSetFinalCrop", "(JIIII)V",
+    {"nativeSetFinalCrop", "(JJIIII)V",
             (void*)nativeSetFinalCrop },
-    {"nativeSetLayerStack", "(JI)V",
+    {"nativeSetLayerStack", "(JJI)V",
             (void*)nativeSetLayerStack },
     {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;",
             (void*)nativeGetBuiltInDisplay },
@@ -840,13 +900,13 @@
             (void*)nativeCreateDisplay },
     {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
             (void*)nativeDestroyDisplay },
-    {"nativeSetDisplaySurface", "(Landroid/os/IBinder;J)V",
+    {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V",
             (void*)nativeSetDisplaySurface },
-    {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V",
+    {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V",
             (void*)nativeSetDisplayLayerStack },
-    {"nativeSetDisplayProjection", "(Landroid/os/IBinder;IIIIIIIII)V",
+    {"nativeSetDisplayProjection", "(JLandroid/os/IBinder;IIIIIIIII)V",
             (void*)nativeSetDisplayProjection },
-    {"nativeSetDisplaySize", "(Landroid/os/IBinder;II)V",
+    {"nativeSetDisplaySize", "(JLandroid/os/IBinder;II)V",
             (void*)nativeSetDisplaySize },
     {"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;",
             (void*)nativeGetDisplayConfigs },
@@ -872,17 +932,17 @@
             (void*)nativeGetAnimationFrameStats },
     {"nativeSetDisplayPowerMode", "(Landroid/os/IBinder;I)V",
             (void*)nativeSetDisplayPowerMode },
-    {"nativeDeferTransactionUntil", "(JLandroid/os/IBinder;J)V",
+    {"nativeDeferTransactionUntil", "(JJLandroid/os/IBinder;J)V",
             (void*)nativeDeferTransactionUntil },
-    {"nativeDeferTransactionUntilSurface", "(JJJ)V",
+    {"nativeDeferTransactionUntilSurface", "(JJJJ)V",
             (void*)nativeDeferTransactionUntilSurface },
-    {"nativeReparentChildren", "(JLandroid/os/IBinder;)V",
+    {"nativeReparentChildren", "(JJLandroid/os/IBinder;)V",
             (void*)nativeReparentChildren } ,
-    {"nativeReparent", "(JLandroid/os/IBinder;)V",
+    {"nativeReparent", "(JJLandroid/os/IBinder;)V",
             (void*)nativeReparent },
-    {"nativeSeverChildren", "(J)V",
+    {"nativeSeverChildren", "(JJ)V",
             (void*)nativeSeverChildren } ,
-    {"nativeSetOverrideScalingMode", "(JI)V",
+    {"nativeSetOverrideScalingMode", "(JJI)V",
             (void*)nativeSetOverrideScalingMode },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
             (void*)nativeGetHandle },
diff --git a/core/jni/eventlog_helper.h b/core/jni/eventlog_helper.h
new file mode 100644
index 0000000..3a05195
--- /dev/null
+++ b/core/jni/eventlog_helper.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef FRAMEWORKS_BASE_CORE_JNI_EVENTLOG_HELPER_H_
+#define FRAMEWORKS_BASE_CORE_JNI_EVENTLOG_HELPER_H_
+
+#include <memory>
+
+#include <fcntl.h>
+
+#include <android-base/macros.h>
+#include <log/log_event_list.h>
+
+#include <log/log.h>
+
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include "core_jni_helpers.h"
+#include "jni.h"
+
+namespace android {
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+class EventLogHelper {
+public:
+    static void Init(JNIEnv* env) {
+        struct { const char *name; jclass *clazz; } gClasses[] = {
+                { EventClassDescriptor, &gEventClass },
+                { "java/lang/Integer", &gIntegerClass },
+                { "java/lang/Long", &gLongClass },
+                { "java/lang/Float", &gFloatClass },
+                { "java/lang/String", &gStringClass },
+                { "java/util/Collection", &gCollectionClass },
+        };
+        struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
+                { &gIntegerClass, "value", "I", &gIntegerValueID },
+                { &gLongClass, "value", "J", &gLongValueID },
+                { &gFloatClass, "value", "F", &gFloatValueID },
+        };
+        struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
+                { &gEventClass, "<init>", "([B)V", &gEventInitID },
+                { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID },
+        };
+
+        for (size_t i = 0; i < NELEM(gClasses); ++i) {
+            ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, gClasses[i].name));
+            *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz.get());
+        }
+        for (size_t i = 0; i < NELEM(gFields); ++i) {
+            *gFields[i].id = GetFieldIDOrDie(env,
+                    *gFields[i].c, gFields[i].name, gFields[i].ft);
+        }
+
+        for (size_t i = 0; i < NELEM(gMethods); ++i) {
+            *gMethods[i].id = GetMethodIDOrDie(env,
+                    *gMethods[i].c, gMethods[i].name, gMethods[i].mt);
+        }
+    }
+
+    static jint writeEventInteger(JNIEnv* env ATTRIBUTE_UNUSED, jobject clazz ATTRIBUTE_UNUSED,
+            jint tag, jint value) {
+        android_log_event_list ctx(tag);
+        ctx << (int32_t)value;
+        return ctx.write(LogID);
+    }
+    static jint writeEventLong(JNIEnv* env ATTRIBUTE_UNUSED, jobject clazz ATTRIBUTE_UNUSED,
+            jint tag, jlong value) {
+        android_log_event_list ctx(tag);
+        ctx << (int64_t)value;
+        return ctx.write(LogID);
+    }
+    static jint writeEventFloat(JNIEnv* env ATTRIBUTE_UNUSED, jobject clazz ATTRIBUTE_UNUSED,
+            jint tag, jfloat value) {
+        android_log_event_list ctx(tag);
+        ctx << (float)value;
+        return ctx.write(LogID);
+    }
+    static jint writeEventString(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED, jint tag,
+            jstring value) {
+        android_log_event_list ctx(tag);
+        // Don't throw NPE -- I feel like it's sort of mean for a logging function
+        // to be all crashy if you pass in NULL -- but make the NULL value explicit.
+        ctx << (value != nullptr ? ScopedUtfChars(env, value).c_str() : "NULL");
+        return ctx.write(LogID);
+    }
+    static jint writeEventArray(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED, jint tag,
+            jobjectArray value) {
+        android_log_event_list ctx(tag);
+
+        if (value == nullptr) {
+            ctx << "[NULL]";
+            return ctx.write(LogID);
+        }
+
+        jsize copied = 0, num = env->GetArrayLength(value);
+        for (; copied < num && copied < 255; ++copied) {
+            if (ctx.status()) break;
+            ScopedLocalRef<jobject> item(env, env->GetObjectArrayElement(value, copied));
+            if (item == nullptr) {
+                ctx << "NULL";
+            } else if (env->IsInstanceOf(item.get(), gStringClass)) {
+                ctx << ScopedUtfChars(env, (jstring) item.get()).c_str();
+            } else if (env->IsInstanceOf(item.get(), gIntegerClass)) {
+                ctx << (int32_t)env->GetIntField(item.get(), gIntegerValueID);
+            } else if (env->IsInstanceOf(item.get(), gLongClass)) {
+                ctx << (int64_t)env->GetLongField(item.get(), gLongValueID);
+            } else if (env->IsInstanceOf(item.get(), gFloatClass)) {
+                ctx << (float)env->GetFloatField(item.get(), gFloatValueID);
+            } else {
+                jniThrowException(env,
+                        "java/lang/IllegalArgumentException",
+                        "Invalid payload item type");
+                return -1;
+            }
+        }
+        return ctx.write(LogID);
+    }
+
+    static void readEvents(JNIEnv* env, int loggerMode, jlong startTime, jobject out) {
+        readEvents(env, loggerMode, nullptr, startTime, out);
+    }
+
+    static void readEvents(JNIEnv* env, int loggerMode, jintArray jTags, jlong startTime,
+            jobject out) {
+        std::unique_ptr<struct logger_list, decltype(&android_logger_list_close)> logger_list(
+                nullptr, android_logger_list_close);
+        if (startTime) {
+            logger_list.reset(android_logger_list_alloc_time(loggerMode,
+                    log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0));
+        } else {
+            logger_list.reset(android_logger_list_alloc(loggerMode, 0, 0));
+        }
+        if (!logger_list) {
+            jniThrowIOException(env, errno);
+            return;
+        }
+
+        if (!android_logger_open(logger_list.get(), LogID)) {
+            jniThrowIOException(env, errno);
+            return;
+        }
+
+        ScopedIntArrayRO tags(env);
+        if (jTags != nullptr) {
+            tags.reset(jTags);
+        }
+
+        while (1) {
+            log_msg log_msg;
+            int ret = android_logger_list_read(logger_list.get(), &log_msg);
+
+            if (ret == 0) {
+                return;
+            }
+            if (ret < 0) {
+                if (ret == -EINTR) {
+                    continue;
+                }
+                if (ret == -EINVAL) {
+                    jniThrowException(env, "java/io/IOException", "Event too short");
+                } else if (ret != -EAGAIN) {
+                    jniThrowIOException(env, -ret);  // Will throw on return
+                }
+                return;
+            }
+
+            if (log_msg.id() != LogID) {
+                continue;
+            }
+
+            int32_t tag = * (int32_t *) log_msg.msg();
+
+            if (jTags != nullptr) {
+                bool found = false;
+                for (size_t i = 0; !found && i < tags.size(); ++i) {
+                    found = (tag == tags[i]);
+                }
+                if (!found) {
+                    continue;
+                }
+            }
+
+            jsize len = ret;
+            ScopedLocalRef<jbyteArray> array(env, env->NewByteArray(len));
+            if (array == nullptr) {
+                return;
+            }
+
+            {
+                ScopedByteArrayRW bytes(env, array.get());
+                memcpy(bytes.get(), log_msg.buf, len);
+            }
+
+            ScopedLocalRef<jobject> event(env,
+                    env->NewObject(gEventClass, gEventInitID, array.get()));
+            if (event == nullptr) {
+                return;
+            }
+
+            env->CallBooleanMethod(out, gCollectionAddID, event.get());
+            if (env->ExceptionCheck() == JNI_TRUE) {
+                return;
+            }
+        }
+    }
+
+private:
+    static jclass gCollectionClass;
+    static jmethodID gCollectionAddID;
+
+    static jclass gEventClass;
+    static jmethodID gEventInitID;
+
+    static jclass gIntegerClass;
+    static jfieldID gIntegerValueID;
+
+    static jclass gLongClass;
+    static jfieldID gLongValueID;
+
+    static jclass gFloatClass;
+    static jfieldID gFloatValueID;
+
+    static jclass gStringClass;
+};
+
+// Explicit instantiation declarations.
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gCollectionClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jmethodID EventLogHelper<LogID, EventClassDescriptor>::gCollectionAddID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gEventClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jmethodID EventLogHelper<LogID, EventClassDescriptor>::gEventInitID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gIntegerClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jfieldID EventLogHelper<LogID, EventClassDescriptor>::gIntegerValueID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gLongClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jfieldID EventLogHelper<LogID, EventClassDescriptor>::gLongValueID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gFloatClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jfieldID EventLogHelper<LogID, EventClassDescriptor>::gFloatValueID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gStringClass;
+
+}  // namespace android
+
+#endif  // FRAMEWORKS_BASE_CORE_JNI_EVENTLOG_HELPER_H_
diff --git a/core/proto/android/content/intent.proto b/core/proto/android/content/intent.proto
new file mode 100644
index 0000000..f2927a7
--- /dev/null
+++ b/core/proto/android/content/intent.proto
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+syntax = "proto3";
+
+option java_package = "android.content";
+option java_multiple_files = true;
+
+import "frameworks/base/core/proto/android/os/patternmatcher.proto";
+
+package android.content;
+
+// Next Tag: 13
+message IntentProto {
+    string action = 1;
+    repeated string categories = 2;
+    string data = 3;
+    string type = 4;
+    string flag = 5;
+    string package = 6;
+    string component = 7;
+    string source_bounds = 8;
+    string clip_data = 9;
+    string extras = 10;
+    int32 content_user_hint = 11;
+    string selector = 12;
+}
+
+// Next Tag: 11
+message IntentFilterProto {
+    repeated string actions = 1;
+    repeated string categories = 2;
+    repeated string data_schemes = 3;
+    repeated android.os.PatternMatcherProto data_scheme_specs = 4;
+    repeated AuthorityEntryProto data_authorities = 5;
+    repeated android.os.PatternMatcherProto data_paths = 6;
+    repeated string data_types = 7;
+    int32 priority = 8;
+    bool has_partial_types = 9;
+    bool get_auto_verify = 10;
+}
+
+message AuthorityEntryProto {
+    string host = 1;
+    bool wild = 2;
+    int32 port = 3;
+}
diff --git a/core/proto/android/os/batterystats.proto b/core/proto/android/os/batterystats.proto
index 86e31d0..8d85038 100644
--- a/core/proto/android/os/batterystats.proto
+++ b/core/proto/android/os/batterystats.proto
@@ -20,6 +20,8 @@
 
 package android.os;
 
+import "frameworks/base/core/proto/android/telephony/signalstrength.proto";
+
 message BatteryStatsProto {
   int32 report_version = 1;
   int64 parcel_version = 2;
@@ -55,6 +57,383 @@
 }
 
 message SystemProto {
+  message Battery {
+    // Wall clock time when the data collection started.
+    // In case of device time manually reset by users:
+    //   start_clock_time_ms keeps the same value in the current collection
+    //   period and changes for later collection periods.
+    int64 start_clock_time_ms = 1;
+    // #times the device has been started since start_clock_time_millis.
+    int64 start_count = 2;
+    // Total realtime duration (= SINCE_UNPLUGGED battery_realtime_millis.)
+    int64 total_realtime_ms = 3;
+    int64 total_uptime_ms = 4;
+    // Realtime duration on battery.
+    int64 battery_realtime_ms = 5;
+    // Uptime duration (i.e., not suspend).
+    // Uptime is anytime the CPUs were on. The radio and Wifi chip
+    // can be running while the CPUs are off.
+    int64 battery_uptime_ms = 6;
+    // Total realtime duration measured with screen off or dozing.
+    int64 screen_off_realtime_ms = 7;
+    // Total uptime duration measured with screen off or dozing.
+    int64 screen_off_uptime_ms = 8;
+    // Total time the screen was dozing while the device was running on battery.
+    // For historical reasons, screen_doze_duration_msec is a subset of
+    // screen_off_realtime_msec.
+    int64 screen_doze_duration_ms = 9;
+    // The estimated real battery capacity, which may be less than the declared
+    // battery capacity (for example, because of battery aging). This field is
+    // less reliable than min(max)_learned_battery_capacity_uah, use those two
+    // fields whenever possible.
+    int64 estimated_battery_capacity_mah = 10;
+    // The minimum learned battery capacity in uAh.
+    int64 min_learned_battery_capacity_uah = 11;
+    // The maximum learned battery capacity in uAh.
+    int64 max_learned_battery_capacity_uah = 12;
+  };
+  Battery battery = 1;
+
+  message BatteryDischarge {
+    // Discharged battery percentage points since the stats were last reset
+    // after charging (lower bound approximation).
+    int32 lower_bound_since_charge = 1;
+    // Upper bound approximation.
+    int32 upper_bound_since_charge = 2;
+    // Discharged points while screen is on.
+    int32 screen_on_since_charge = 3;
+    // Discharged points while screen is off.
+    int32 screen_off_since_charge = 4;
+    // Discharged points while screen was dozing. For historical reasons,
+    // screen_doze_since_charge is a subset of screen_off_since_charge.
+    int32 screen_doze_since_charge = 5;
+    // Total amount of battery discharged in mAh. This will only be non-zero for
+    // devices that report battery discharge via a coulomb counter.
+    int64 total_mah = 6;
+    // Total amount of battery discharged while the screen was off in mAh.
+    // This will only be non-zero for devices that report battery discharge
+    // via a coulomb counter.
+    int64 total_mah_screen_off = 7;
+    // Total amount of battery discharged while the screen was dozing in mAh.
+    // This will only be non-zero for devices that report battery discharge
+    // via a coulomb counter. For historical reasons, total_mah_screen_doze is
+    // a subset of total_mah_screen_off.
+    int64 total_mah_screen_doze = 8;
+  };
+  BatteryDischarge battery_discharge = 2;
+
+  oneof time_remaining {
+    // Approximation for how much time remains until the battery is fully
+    // charged. The device will print -1 if there wasn't enough data to
+    // calculate an estimate, or if the battery is currently discharging.
+    int64 charge_time_remaining_ms = 3;
+    // Approximation for how much time remains until the battery is fully
+    // discharged. The device will print -1 if there wasn't enough data to
+    // calculate an estimate, or if the battery is currently charging.
+    int64 discharge_time_remaining_ms = 4;
+  }
+
+  // BatteryLevelStep tracks data for which conditions were continuously held for
+  // the entire duration. Field for which the conditions were not consistent
+  // for the entire duration should be marked MIXED.
+  message BatteryLevelStep {
+    // How long the battery was at the current level.
+    int64 duration_ms = 1;
+    // Battery level
+    int32 level = 2;
+
+    // State of the display. A special enum is used rather than
+    // DisplayProto.State because a MIXED value needs to be in the enum, and
+    // batterystats doesn't care about all of the different display states.
+    enum DisplayState {
+      DS_MIXED = 0;
+      DS_ON = 1;
+      DS_OFF = 2;
+      DS_DOZE = 3;
+      DS_DOZE_SUSPEND = 4;
+      // Any display state error that comes through should be sent to hackbod@.
+      DS_ERROR = 5;
+    }
+    // The state of the display for the entire battery level step. MIXED is used
+    // if there were multiple states for this step.
+    DisplayState display_state = 3;
+
+    // Indicates status in power save mode.
+    enum PowerSaveMode {
+      PSM_MIXED = 0;
+      PSM_ON = 1;
+      PSM_OFF = 2;
+    }
+    // Battery Saver mode for the entire battery level step. MIXED is used
+    // if there were multiple states for this step.
+    PowerSaveMode power_save_mode = 4;
+
+    // Indicates status in idle mode.
+    enum IdleMode {
+      IM_MIXED = 0;
+      IM_ON = 2;
+      IM_OFF = 3;
+    }
+    // Doze mode for the entire battery level step. MIXED is used if there were
+    // multiple states for this step.
+    IdleMode idle_mode = 5;
+  };
+  // Battery level steps when the device was charging.
+  repeated BatteryLevelStep charge_step = 5;
+  // Battery level steps when the device was discharging.
+  repeated BatteryLevelStep discharge_step = 6;
+
+  // All CPU frequencies of the device.
+  repeated int64 cpu_frequency = 7;
+
+  message DataConnection {
+    enum Name {
+      NONE = 0;
+      GPRS = 1;
+      EDGE = 2;
+      UMTS = 3;
+      CDMA = 4;
+      EVDO_0 = 5;
+      EVDO_A = 6;
+      ONE_X_RTT = 7; // 1xRTT.
+      HSDPA = 8;
+      HSUPA = 9;
+      HSPA = 10;
+      IDEN = 11;
+      EVDO_B = 12;
+      LTE = 13;
+      EHRPD = 14;
+      HSPAP = 15;
+      OTHER = 16;
+    };
+    Name name = 1;
+    TimerProto total = 2;
+  };
+  repeated DataConnection data_connection = 8;
+
+  ControllerActivityProto global_bluetooth_controller = 9;
+  ControllerActivityProto global_modem_controller = 10;
+  ControllerActivityProto global_wifi_controller = 11;
+
+  message GlobalNetwork {
+    // Total Bytes received on mobile connections.
+    int64 mobile_bytes_rx = 1;
+    // Total Bytes transmitted on mobile connections.
+    int64 mobile_bytes_tx = 2;
+    // Total Bytes received on wifi connections.
+    int64 wifi_bytes_rx = 3;
+    // Total Bytes transmitted on wifi connections.
+    int64 wifi_bytes_tx = 4;
+    // Total Packets received on mobile connections.
+    int64 mobile_packets_rx = 5;
+    // Total Packets transmitted on mobile connections.
+    int64 mobile_packets_tx = 6;
+    // Total Packets received on wifi connections.
+    int64 wifi_packets_rx = 7;
+    // Total Packets transmitted on wifi connections.
+    int64 wifi_packets_tx = 8;
+    // Total Bytes received on bluetooth connections.
+    int64 bt_bytes_rx = 9;
+    // Total Bytes transmitted on bluetooth connections.
+    int64 bt_bytes_tx = 10;
+  };
+  GlobalNetwork global_network = 12;
+
+  message GlobalWifi {
+    // The amount of time that wifi has been on while the device was running on
+    // battery.
+    int64 on_duration_ms = 1;
+    // The amount of time that wifi has been on and the driver has been in the
+    // running state while the device was running on battery.
+    int64 running_duration_ms = 2;
+  }
+  GlobalWifi global_wifi = 13;
+
+  // Kernel wakelock metrics are only recorded when the device is unplugged
+  // *and* the screen is off.
+  message KernelWakelock {
+    string name = 1;
+    // Kernel wakelock stats aren't apportioned across all kernel wakelocks (as
+    // app wakelocks stats are).
+    TimerProto total = 2;
+    // The kernel doesn't have the data to enable printing out current and max
+    // durations.
+  };
+  repeated KernelWakelock kernel_wakelock = 14;
+
+  message Misc {
+    int64 screen_on_duration_ms = 1;
+    int64 phone_on_duration_ms = 2;
+    int64 full_wakelock_total_duration_ms = 3;
+    // The total elapsed time that a partial wakelock was held. This duration
+    // does not double count wakelocks held at the same time.
+    int64 partial_wakelock_total_duration_ms = 4;
+    int64 mobile_radio_active_duration_ms = 5;
+    // The time that is the difference between the mobile radio time we saw
+    // based on the elapsed timestamp when going down vs. the given time stamp
+    // from the radio.
+    int64 mobile_radio_active_adjusted_time_ms = 6;
+    int32 mobile_radio_active_count = 7;
+    // The amount of time that the mobile network has been active (in a high
+    // power state) but not being able to blame on an app.
+    int32 mobile_radio_active_unknown_duration_ms = 8;
+    // Total amount of time the device was in the interactive state.
+    int64 interactive_duration_ms = 9;
+    int64 battery_saver_mode_enabled_duration_ms = 10;
+    int32 num_connectivity_changes = 11;
+    // Amount of time the device was in deep Doze.
+    int64 deep_doze_enabled_duration_ms = 12;
+    // How many times the device went into deep Doze mode.
+    int32 deep_doze_count = 13;
+    // Amount of time the device was idling in deep Doze. Idling time
+    // encompasses "doze" time and the maintenance windows that allow apps to
+    // operate.
+    int64 deep_doze_idling_duration_ms = 14;
+    // How many times the device idling for deep Doze mode.
+    int32 deep_doze_idling_count = 15;
+    int64 longest_deep_doze_duration_ms = 16;
+    // Amount of time the device was in Doze Light.
+    int64 light_doze_enabled_duration_ms = 17;
+    // How many times the device went into Doze Light mode.
+    int32 light_doze_count = 18;
+    // Amount of time the device was idling in Doze Light. Idling time
+    // encompasses "doze" time and the maintenance windows that allow apps to
+    // operate.
+    int64 light_doze_idling_duration_ms = 19;
+    // How many times the device idling for Doze Light mode.
+    int32 light_doze_idling_count = 20;
+    int64 longest_light_doze_duration_ms = 21;
+  }
+  Misc misc = 15;
+
+  message PhoneSignalStrength {
+    android.telephony.SignalStrengthProto.StrengthName name = 1;
+    TimerProto total = 2;
+  };
+  repeated PhoneSignalStrength phone_signal_strength = 16;
+
+  message PowerUseItem {
+    enum Sipper {
+      UNKNOWN_SIPPER = 0;
+      IDLE = 1;
+      CELL = 2;
+      PHONE = 3;
+      WIFI = 4;
+      BLUETOOTH = 5;
+      FLASHLIGHT = 6;
+      SCREEN = 7;
+      USER = 8;
+      UNACCOUNTED = 9;
+      OVERCOUNTED = 10;
+      CAMERA = 11;
+      MEMORY = 12;
+    };
+    Sipper name = 1;
+    // UID, only valid for the USER sipper.
+    int32 uid = 2;
+    // Estimated power use in mAh.
+    double computed_power_mah = 3;
+    // Starting in Oreo, Battery Settings has two modes to display the battery
+    // info. The first is "app usage list". In this mode, items with should_hide
+    // enabled are hidden.
+    bool should_hide = 4;
+    // Smeared power from screen usage. Screen usage power is split and smeared
+    // among apps, based on activity time.
+    double screen_power_mah = 5;
+    // Smeared power using proportional method. Power usage from hidden sippers
+    // is smeared to all apps proportionally (except for screen usage).
+    double proportional_smear_mah = 6;
+  };
+  repeated PowerUseItem power_use_item = 17;
+
+  message PowerUseSummary {
+    double battery_capacity_mah = 1;
+    double computed_power_mah = 2;
+    // Lower bound of actual power drained.
+    double min_drained_power_mah = 3;
+    // Upper bound of actual power drained.
+    double max_drained_power_mah = 4;
+  };
+  PowerUseSummary power_use_summary = 18;
+
+  message ResourcePowerManager {
+    string name = 1;
+    TimerProto total = 2;
+    TimerProto screen_off = 3;
+  }
+  ResourcePowerManager resource_power_manager = 19;
+
+  message ScreenBrightness {
+    enum Name {
+      DARK = 0; // Not screen-off.
+      DIM = 1;
+      MEDIUM = 2;
+      LIGHT = 3;
+      BRIGHT = 4;
+    };
+    Name name = 1;
+    TimerProto total = 2;
+  };
+  repeated ScreenBrightness screen_brightness = 20;
+
+  // Duration and number of times trying to acquire a signal
+  TimerProto signal_scanning = 21;
+
+  message WakeupReason {
+    string name = 1;
+    TimerProto total = 2;
+  };
+  repeated WakeupReason wakeup_reason = 22;
+
+  message WifiSignalStrength {
+    enum Name {
+      NONE = 0;
+      POOR = 1;
+      MODERATE = 2;
+      GOOD = 3;
+      GREAT = 4;
+    };
+    Name name = 1;
+    TimerProto total = 2;
+  };
+  repeated WifiSignalStrength wifi_signal_strength = 23;
+
+  message WifiState {
+    enum Name {
+      OFF = 0;
+      OFF_SCANNING = 1;
+      ON_NO_NETWORKS = 2;
+      ON_DISCONNECTED = 3;
+      ON_CONNECTED_STA = 4;
+      ON_CONNECTED_P2P = 5;
+      ON_CONNECTED_STA_P2P = 6;
+      SOFT_AP = 7;
+    };
+    Name name = 1;
+    TimerProto total = 2;
+  };
+  repeated WifiState wifi_state = 24;
+
+  message WifiSupplicantState {
+    enum Name {
+      INVALID = 0;
+      DISCONNECTED = 1;
+      INTERFACE_DISABLED = 2;
+      INACTIVE = 3;
+      SCANNING = 4;
+      AUTHENTICATING = 5;
+      ASSOCIATING = 6;
+      ASSOCIATED = 7;
+      FOUR_WAY_HANDSHAKE = 8;
+      GROUP_HANDSHAKE = 9;
+      COMPLETED = 10;
+      DORMANT = 11;
+      UNINITIALIZED = 12;
+    };
+    Name name = 1;
+    TimerProto total = 2;
+  };
+  repeated WifiSupplicantState wifi_supplicant_state = 25;
 }
 
 message TimerProto {
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index b3a606f..884d740 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -32,6 +32,7 @@
 import "frameworks/base/core/proto/android/service/power.proto";
 import "frameworks/base/core/proto/android/service/print.proto";
 import "frameworks/base/core/proto/android/service/procstats.proto";
+import "frameworks/base/core/proto/android/server/activitymanagerservice.proto";
 import "frameworks/base/core/proto/android/providers/settings.proto";
 import "frameworks/base/core/proto/android/os/incidentheader.proto";
 import "frameworks/base/core/proto/android/os/kernelwake.proto";
@@ -108,4 +109,17 @@
         (section).type = SECTION_DUMPSYS,
         (section).args = "procstats --proto"
     ];
+
+    com.android.server.am.proto.ActivityStackSupervisorProto activities = 3012 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "activity --proto activities"
+    ];
+
+    com.android.server.am.proto.BroadcastProto broadcasts = 3013 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "activity --proto broadcasts"
+    ];
+
+    com.android.server.am.proto.ServiceProto amservices = 3014;
+    com.android.server.am.proto.ProcessProto amprocesses = 3015;
 }
diff --git a/cmds/statsd/src/parse_util.h b/core/proto/android/os/patternmatcher.proto
similarity index 62%
copy from cmds/statsd/src/parse_util.h
copy to core/proto/android/os/patternmatcher.proto
index 8b82e7b..cd68245 100644
--- a/cmds/statsd/src/parse_util.h
+++ b/core/proto/android/os/patternmatcher.proto
@@ -13,24 +13,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef PARSE_UTIL_H
-#define PARSE_UTIL_H
 
-#include "DropboxWriter.h"
-#include "LogReader.h"
+syntax = "proto3";
 
-#include <log/logprint.h>
+option java_multiple_files = true;
 
-namespace android {
-namespace os {
-namespace statsd {
+package android.os;
 
-EventMetricData parse(log_msg msg);
+message PatternMatcherProto {
+    string pattern = 1;
 
-int getTagId(log_msg msg);
+    enum Type {
+        TYPE_LITERAL = 0;
+        TYPE_PREFIX = 1;
+        TYPE_SIMPLE_GLOB = 2;
+        TYPE_ADVANCED_GLOB = 3;
+    }
+    Type type = 2;
 
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // PARSE_UTIL_H
+    // This data is too much for dump
+    // repeated int32 parsed_pattern = 3;
+}
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index d5ecacc..fe5e3f1 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -16,8 +16,11 @@
 
 syntax = "proto3";
 
+import "frameworks/base/core/proto/android/content/intent.proto";
+import "frameworks/base/core/proto/android/server/intentresolver.proto";
 import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
 import "frameworks/base/core/proto/android/graphics/rect.proto";
+import "frameworks/base/core/proto/android/os/looper.proto";
 
 package com.android.server.am.proto;
 
@@ -25,6 +28,12 @@
 
 message ActivityManagerServiceProto {
   ActivityStackSupervisorProto activities = 1;
+
+  BroadcastProto broadcasts = 2;
+
+  ServiceProto services = 3;
+
+  ProcessProto processes = 4;
 }
 
 message ActivityStackSupervisorProto {
@@ -81,4 +90,86 @@
 message KeyguardControllerProto {
   bool keyguard_showing = 1;
   bool keyguard_occluded = 2;
-}
\ No newline at end of file
+}
+
+message BroadcastProto {
+  repeated ReceiverListProto  receiver_list = 1;
+
+  .com.android.server.IntentResolverProto receiver_resolver = 2;
+
+  repeated BroadcastQueueProto broadcast_queue = 3;
+
+  repeated StickyBroadcastProto sticky_broadcasts = 4;
+
+  message MainHandler {
+    string handler = 1;
+    .android.os.LooperProto looper = 2;
+  }
+  MainHandler handler = 5;
+}
+
+message ReceiverListProto {
+  ProcessRecordProto app = 1;
+  int32 pid = 2;
+  int32 uid = 3;
+  int32 user = 4;
+  BroadcastRecordProto current = 5;
+  bool linked_to_death = 6;
+  repeated BroadcastFilterProto filters = 7;
+  string hex_hash = 8; // this hash is used to find the object in IntentResolver
+}
+
+message ProcessRecordProto {
+  int32 pid = 1;
+  string process_name = 2;
+  int32 uid = 3;
+  int32 user_id = 4;
+  int32 app_id = 5;
+  int32 isolated_app_id = 6;
+}
+
+message BroadcastRecordProto {
+  int32 user_id = 1;
+  string intent_action = 2;
+}
+
+message BroadcastFilterProto {
+  .android.content.IntentFilterProto intent_filter = 1;
+  string required_permission = 2;
+  string hex_hash = 3; // used to find the object in IntentResolver
+  int32 owning_user_id = 4;
+}
+
+message BroadcastQueueProto {
+  string queue_name = 1;
+  repeated BroadcastRecordProto parallel_broadcasts = 2;
+  repeated BroadcastRecordProto ordered_broadcasts = 3;
+  BroadcastRecordProto pending_broadcast = 4;
+  repeated BroadcastRecordProto historical_broadcasts = 5;
+
+  message BroadcastSummary {
+    .android.content.IntentProto intent = 1;
+    int64 enqueue_clock_time_ms = 2;
+    int64 dispatch_clock_time_ms = 3;
+    int64 finish_clock_time_ms = 4;
+  }
+  repeated BroadcastSummary historical_broadcasts_summary = 6;
+}
+
+message StickyBroadcastProto {
+  int32 user = 1;
+
+  message StickyAction {
+    string name = 1;
+    repeated .android.content.IntentProto intents = 2;
+  }
+  repeated StickyAction actions = 2;
+}
+
+message ServiceProto {
+  // TODO: "dumpsys activity --proto services"
+}
+
+message ProcessProto {
+  // TODO: "dumpsys activity --proto processes"
+}
diff --git a/core/proto/android/server/intentresolver.proto b/core/proto/android/server/intentresolver.proto
new file mode 100644
index 0000000..62ec2ea
--- /dev/null
+++ b/core/proto/android/server/intentresolver.proto
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+
+package com.android.server;
+
+message IntentResolverProto {
+
+    message ArrayMapEntry {
+        string key = 1;
+        repeated string values = 2;
+    }
+
+    repeated ArrayMapEntry full_mime_types = 1;
+    repeated ArrayMapEntry base_mime_types = 2;
+    repeated ArrayMapEntry wild_mime_types = 3;
+    repeated ArrayMapEntry schemes = 4;
+    repeated ArrayMapEntry non_data_actions = 5;
+    repeated ArrayMapEntry mime_typed_actions = 6;
+}
+
diff --git a/cmds/statsd/src/parse_util.h b/core/proto/android/telephony/signalstrength.proto
similarity index 60%
copy from cmds/statsd/src/parse_util.h
copy to core/proto/android/telephony/signalstrength.proto
index 8b82e7b..ff230cb 100644
--- a/cmds/statsd/src/parse_util.h
+++ b/core/proto/android/telephony/signalstrength.proto
@@ -13,24 +13,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef PARSE_UTIL_H
-#define PARSE_UTIL_H
 
-#include "DropboxWriter.h"
-#include "LogReader.h"
+syntax = "proto3";
 
-#include <log/logprint.h>
+option java_package = "android.telephony";
+option java_multiple_files = true;
 
-namespace android {
-namespace os {
-namespace statsd {
+package android.telephony;
 
-EventMetricData parse(log_msg msg);
-
-int getTagId(log_msg msg);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // PARSE_UTIL_H
+/**
+ * An android.telephony.SignalStrength object.
+ */
+message SignalStrengthProto {
+  enum StrengthName {
+    SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
+    SIGNAL_STRENGTH_POOR = 1;
+    SIGNAL_STRENGTH_MODERATE = 2;
+    SIGNAL_STRENGTH_GOOD = 3;
+    SIGNAL_STRENGTH_GREAT = 4;
+  }
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6a9afbc..37b5d5d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -551,6 +551,9 @@
     <protected-broadcast android:name="android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED" />
     <protected-broadcast android:name="com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER" />
 
+    <!-- Made protected in P (was introduced in JB-MR2) -->
+    <protected-broadcast android:name="android.intent.action.GET_RESTRICTION_ENTRIES" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -963,7 +966,7 @@
         android:permissionGroup="android.permission-group.MICROPHONE"
         android:label="@string/permlab_recordAudio"
         android:description="@string/permdesc_recordAudio"
-        android:protectionLevel="dangerous"/>
+        android:protectionLevel="dangerous|instant"/>
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the UCE Service                              -->
@@ -3584,6 +3587,10 @@
     <permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE"
         android:protectionLevel="signature|development|instant|appop" />
 
+    <!-- @hide Allows system components to access all app shortcuts. -->
+    <permission android:name="android.permission.ACCESS_SHORTCUTS"
+        android:protectionLevel="signature" />
+
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 5d6f04f..e614916 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Werkprofiel is weens ontbrekende administrasieprogram uitgevee"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Die werkprofiel se administrasieprogram ontbreek of is korrup. Gevolglik is jou werkprofiel en verwante data uitgevee. Kontak jou administrateur vir bystand."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Jou werkprofiel is nie meer op hierdie toestel beskikbaar nie"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Te veel wagwoordpogings"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Toestel word bestuur"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Jou organisasie bestuur hierdie toestel en kan netwerkverkeer monitor. Tik vir besonderhede."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Jou toestel sal uitgevee word"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Opletberigte"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kleinhandeldemonstrasie"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-verbinding"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Program loop tans"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Programme wat batterykrag gebruik"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruik tans batterykrag"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> programme gebruik tans batterykrag"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Invoermetode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksaksies"</string>
     <string name="email" msgid="4560673117055050403">"E-pos"</string>
-    <string name="dial" msgid="4204975095406423102">"Foon"</string>
-    <string name="map" msgid="6068210738233985748">"Kaarte"</string>
-    <string name="browse" msgid="6993590095938149861">"Blaaier"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontak"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Bergingspasie word min"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Sommige stelselfunksies werk moontlik nie"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nie genoeg berging vir die stelsel nie. Maak seker jy het 250 MB spasie beskikbaar en herbegin."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM word nie toegelaat nie"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Foon word nie toegelaat nie"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Opspringvenster"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ffae89c..65676b4 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ማንቂያዎች"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"የችርቻሮ ማሳያ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"የዩኤስቢ ግንኙነት"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"APP እየሠራ ነው"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ባትሪ በመፍጀት ላይ ያሉ መተግበሪያዎች"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ባትሪ እየተጠቀመ ነው"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> መተግበሪያዎች ባትሪ እየተጠቀሙ ነው"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ግቤት ስልት"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"የፅሁፍ እርምጃዎች"</string>
     <string name="email" msgid="4560673117055050403">"ኢሜይል"</string>
-    <string name="dial" msgid="4204975095406423102">"ስልክ"</string>
-    <string name="map" msgid="6068210738233985748">"ካርታዎች"</string>
-    <string name="browse" msgid="6993590095938149861">"አሳሽ"</string>
-    <string name="sms" msgid="8250353543787396737">"ኤስኤምኤስ"</string>
-    <string name="add_contact" msgid="7990645816259405444">"ዕውቂያ"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"የማከማቻ ቦታ እያለቀ ነው"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"አንዳንድ የስርዓት ተግባራት ላይሰሩ ይችላሉ"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ለስርዓቱ የሚሆን በቂ ቦታ የለም። 250 ሜባ ነጻ ቦታ እንዳለዎት ያረጋግጡና ዳግም ያስጀምሩ።"</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"ሲም አይፈቀድም"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ስልክ አይፈቀድም"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"ብቅ-ባይ መስኮት"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4b20e74..212b9a4 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -180,8 +180,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"تم حذف الملف الشخصي للعمل نتيجة فقد تطبيق المشرف"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"تطبيق المشرف للملف الشخصي للعمل مفقود أو تالف لذا تم حذف الملف الشخصي للعمل والبيانات ذات الصلة. اتصل بالمشرف للحصول على المساعدة."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"لم يعد ملفك الشخصي للعمل متاحًا على هذا الجهاز"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"تم إجراء محاولات كثيرة جدًا لإدخال كلمة المرور"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"تتم إدارة الجهاز"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"تدير مؤسستك هذا الجهاز ويمكنها مراقبة حركة بيانات الشبكة. يمكنك النقر للحصول على تفاصيل."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"سيتم محو بيانات جهازك."</string>
@@ -262,6 +261,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"التنبيهات"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"عرض توضيحي لبائع التجزئة"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"‏اتصال USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"التطبيق قيد التشغيل"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"التطبيقات التي تستهلك البطارية"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"يستخدم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> البطارية"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"تستخدم <xliff:g id="NUMBER">%1$d</xliff:g> من التطبيقات البطارية"</string>
@@ -1059,11 +1059,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"طريقة الإرسال"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"إجراءات النص"</string>
     <string name="email" msgid="4560673117055050403">"بريد إلكتروني"</string>
-    <string name="dial" msgid="4204975095406423102">"الهاتف"</string>
-    <string name="map" msgid="6068210738233985748">"الخرائط"</string>
-    <string name="browse" msgid="6993590095938149861">"المتصفح"</string>
-    <string name="sms" msgid="8250353543787396737">"‏رسالة SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"جهة اتصال"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"مساحة التخزين منخفضة"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"قد لا تعمل بعض وظائف النظام"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ليست هناك سعة تخزينية كافية للنظام. تأكد من أنه لديك مساحة خالية تبلغ ٢٥٠ ميغابايت وأعد التشغيل."</string>
@@ -1930,4 +1935,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"‏غير مسموح باستخدام SIM"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"غير مسموح باستخدام الهاتف"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"نافذة منبثقة"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 7ff8d04..e334f64 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Siqnallar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Pərakəndə demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB əlaqə"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Tətbiq işləyir"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Batareyadan istifadə edən tətbiqlər"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> batareyadan istifadə edir"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> tətbiq batareyadan istifadə edir"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Daxiletmə metodu"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Mətn əməliyyatları"</string>
     <string name="email" msgid="4560673117055050403">"E-poçt"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Xəritə"</string>
-    <string name="browse" msgid="6993590095938149861">"Brauzer"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Yaddaş yeri bitir"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bəzi sistem funksiyaları işləməyə bilər"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sistem üçün yetərincə yaddaş ehtiyatı yoxdur. 250 MB yaddaş ehtiyatının olmasına əmin olun və yenidən başladın."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-ə icazə verilmir"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefona icazə verilmir"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Popap Pəncərəsi"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index bc1e5ab..a558ace 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -174,8 +174,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Profil za Work je izbrisan jer nedostaje aplikacija za administratore"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Aplikacija za administratore na profilu za Work nedostaje ili je oštećena. Zbog toga su profil za Work i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Profil za Work više nije dostupan na ovom uređaju"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Previše pokušaja unosa lozinke"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Uređajem se upravlja"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će biti obrisan"</string>
@@ -253,6 +252,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Obaveštenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Režim demonstracije za maloprodajne objekte"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplikacija je pokrenuta"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacije koje troše bateriju"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Aplikacije (<xliff:g id="NUMBER">%1$d</xliff:g>) koriste bateriju"</string>
@@ -999,11 +999,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Metod unosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje u vezi sa tekstom"</string>
     <string name="email" msgid="4560673117055050403">"Pošalji imejl"</string>
-    <string name="dial" msgid="4204975095406423102">"Pozovi"</string>
-    <string name="map" msgid="6068210738233985748">"Mape"</string>
-    <string name="browse" msgid="6993590095938149861">"Pregledač"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Memorijski prostor je na izmaku"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke sistemske funkcije možda ne funkcionišu"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno memorijskog prostora za sistem. Uverite se da imate 250 MB slobodnog prostora i ponovo pokrenite."</string>
@@ -1825,4 +1830,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM kartica nije dozvoljena"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon nije dozvoljen"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Iskačući prozor"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"i još <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index b643078..84cbc9f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -176,8 +176,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Працоўны профіль выдалены з-за адсутнасці праграмы адміністратара"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Праграма адміністратара для працоўнага профілю адсутнічае або пашкоджана. У выніку гэтага ваш працоўны профіль і звязаныя з ім даныя былі выдалены. Звярніцеся па дапамогу да адміністратара."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Ваш працоўны профіль больш не даступны на гэтай прыладзе"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Занадта шмат спроб уводу пароля"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Прылада знаходзіцца пад кіраваннем"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам. Дакраніцеся для атрымання дадатковай інфармацыі."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Даныя вашай прылады будуць сцерты"</string>
@@ -256,6 +255,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Абвесткi"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Дэманстрацыйны рэжым для пунктаў продажу"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Падключэнне USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Праграма працуе"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Праграмы, якія выкарыстоўваюць акумулятар"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> выкарыстоўвае акумулятар"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Наступная колькасць праграм выкарыстоўваюць акумулятар: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
@@ -1019,11 +1019,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Метад уводу"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дзеянні з тэкстам"</string>
     <string name="email" msgid="4560673117055050403">"Электронная пошта"</string>
-    <string name="dial" msgid="4204975095406423102">"Тэлефон"</string>
-    <string name="map" msgid="6068210738233985748">"Карты"</string>
-    <string name="browse" msgid="6993590095938149861">"Браўзер"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Кантакт"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Месца для захавання на зыходзе"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некаторыя сістэмныя функцыі могуць не працаваць"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Не хапае сховішча для сістэмы. Пераканайцеся, што ў вас ёсць 250 МБ свабоднага месца, і перазапусціце."</string>
@@ -1860,4 +1865,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-карта не дапускаецца"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Тэлефон не дапускаецца"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Выплыўное акно"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 44df773..362a4e6 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Сигнали"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демонстрационен режим за магазини"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB връзка"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Приложението работи"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Приложения, използващи батерията"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> използва батерията"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> приложения използват батерията"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Метод на въвеждане"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Действия с текста"</string>
     <string name="email" msgid="4560673117055050403">"Имейл"</string>
-    <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="6068210738233985748">"Карти"</string>
-    <string name="browse" msgid="6993590095938149861">"Браузър"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Контакт"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Мястото в хранилището е на изчерпване"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Възможно е някои функции на системата да не работят"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"За системата няма достатъчно място в хранилището. Уверете се, че имате свободни 250 МБ, и рестартирайте."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM картата не е разрешена"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Телефонът не е разрешен"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Изскачащ прозорец"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 76a6b0e..0d03942 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"প্রশাসক অ্যাপ না থাকায় কর্মস্থলের প্রোফাইল মুছে ফেলা হয়েছে"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"কর্মস্থলের প্রোফাইলের প্রশাসক অ্যাপটি হয় নেই, অথবা সেটি ক্ষতিগ্রস্ত হয়েছে৷ এর ফলে আপনার কর্মস্থলের প্রোফাইল এবং সম্পর্কিত ডেটা মুছে ফেলা হয়েছে৷ সহায়তার জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন৷"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"আপনার কর্মস্থলের প্রোফাইলটি আর এই ডিভাইসে নেই"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"বহুবার ভুল পাসওয়ার্ড দিয়েছেন"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ডিভাইসটি পরিচালনা করা হচ্ছে"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"আপনার প্রতিষ্ঠান এই ডিভাইসটি পরিচালনা করে এবং এটির নেটওয়ার্ক ট্রাফিকের উপরে নজর রাখতে পারে। বিশদ বিবরণের জন্য ট্যাপ করুন।,"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"আপনার ডিভাইসটি মুছে ফেলা হবে"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"সতর্কতা"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"খুচরা বিক্রয়ের ডেমো"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB সংযোগ"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"কিছু অ্যাপ ব্যাটারি ব্যবহার করছে"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপটি ব্যাটারি ব্যবহার করছে"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g>টি অ্যাপ ব্যাটারি ব্যবহার করছে"</string>
@@ -403,7 +404,7 @@
     <string name="permlab_vibrate" msgid="7696427026057705834">"ভাইব্রেশন নিয়ন্ত্রণ করুন"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"অ্যাপ্লিকেশানকে কম্পক নিয়ন্ত্রণ করতে দেয়৷"</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"সরাসরি ফোন নম্বরগুলিতে কল করে"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"অ্যাপ্লিকেশানটিকে আপনার হস্তক্ষেপ ছাড়াই ফোন নম্বরগুলিতে কল করতে মঞ্জুর করে৷ এটি অপ্রত্যাশিত পরিমাণ খরচা বা কলের কারণ হতে পারে৷ মনে রাখবেন, এটি অ্যাপ্লিকেশানটির দ্বারা জরুরি নম্বরগুলিতে কল করাকে অনুমতি দেয় না৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার সম্মতি ছাড়াই কল করার ফলে আপনাকে অহেতুক অর্থ প্রদান করতে হতে পারে৷"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"অ্যাপ্লিকেশানটিকে আপনার হস্তক্ষেপ ছাড়াই ফোন নম্বরগুলিতে কল করতে মঞ্জুর করে৷ এটি অপ্রত্যাশিত পরিমাণ খরচা বা কলের কারণ হতে পারে৷ মনে রাখবেন, এটি অ্যাপ্লিকেশানটির দ্বারা জরুরি নম্বরগুলিতে কল করাকে অনুমতি দেয় না৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার সম্মতি ছাড়াই কল করার ফলে আপনাকে অহেতুক পেমেন্ট করতে হতে পারে৷"</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS পরিষেবাতে অ্যাক্সেস"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"আপনার হস্তক্ষেপ ছাড়াই কল করতে অ্যাপ্লিকেশানটিকে IMS পরিষেবা ব্যবহারের অনুমতি দিন৷"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ফোনের স্থিতি এবং পরিচয় পড়ুন"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ইনপুট পদ্ধতি"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"পাঠ্য ক্রিয়াগুলি"</string>
     <string name="email" msgid="4560673117055050403">"ইমেল"</string>
-    <string name="dial" msgid="4204975095406423102">"ফোন করুন"</string>
-    <string name="map" msgid="6068210738233985748">"মানচিত্র"</string>
-    <string name="browse" msgid="6993590095938149861">"ব্রাউজার"</string>
-    <string name="sms" msgid="8250353543787396737">"এসএমএস পাঠান"</string>
-    <string name="add_contact" msgid="7990645816259405444">"পরিচিতি যোগ করুন"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"স্টোরেজ পূর্ণ হতে চলেছে"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"কিছু কিছু সিস্টেম ক্রিয়াকলাপ কাজ নাও করতে পারে"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"সিস্টেমের জন্য যথেষ্ট স্টোরেজ নেই৷ আপনার কাছে ২৫০এমবি ফাঁকা স্থান রয়েছে কিনা সে বিষয়ে নিশ্চিত হন এবং সিস্টেম চালু করুন৷"</string>
@@ -1790,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"সিম অনুমোদিত নয়"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ফোন অনুমোদিত নয়"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"পপ-আপ উইন্ডো"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>টি"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 0778b0d..3b2e406 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -174,8 +174,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Radni profil je izbrisan jer nedostaje aplikacija administratora"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Nedostaje aplikacija administratora za radni profil ili je neispravna. Zbog toga su vaš radni profil i povezani podaci izbrisani. Obratite administratoru za pomoć."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Radni profil više nije dostupan na ovom uređaju"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Previše puta ste pokušali otključati uređaj"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Uređajem se upravlja."</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni saobraćaj. Dodirnite za detalje."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će biti izbrisan"</string>
@@ -253,6 +252,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Promotivna demonstracija u maloprodaji"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Pokrenuta je aplikacija"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacije koje troše bateriju"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> troši bateriju"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Broj aplikacija koje troše bateriju: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
@@ -999,11 +999,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Akcije za tekst"</string>
     <string name="email" msgid="4560673117055050403">"E-pošta"</string>
-    <string name="dial" msgid="4204975095406423102">"Pozovi"</string>
-    <string name="map" msgid="6068210738233985748">"Mape"</string>
-    <string name="browse" msgid="6993590095938149861">"Preglednik"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke funkcije sistema možda neće raditi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno prostora za sistem. Obezbijedite 250MB slobodnog prostora i ponovo pokrenite uređaj."</string>
@@ -1827,4 +1832,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM kartica nije dozvoljena"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon nije dozvoljen"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Iskočni prozor"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index d910bf7..f7ea7ee 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"S\'ha suprimit el perfil professional perquè falta l\'aplicació d\'administració"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Falta l\'aplicació d\'administració del perfil professional o està malmesa. Com a conseqüència, s\'han suprimit el teu perfil professional i les dades relacionades. Contacta amb l\'administrador per obtenir ajuda."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"El teu perfil professional ja no està disponible en aquest dispositiu"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Has intentat introduir la contrasenya massa vegades"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"El dispositiu està gestionat"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"La teva organització gestiona aquest dispositiu i és possible que supervisi el trànsit de xarxa. Toca per obtenir més informació."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"El contingut del dispositiu s\'esborrarà"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demostració comercial"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connexió USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"S\'està executant una aplicació"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicacions que consumeixen bateria"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> està consumint bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacions estan consumint bateria"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Mètode d\'introducció de text"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Accions de text"</string>
     <string name="email" msgid="4560673117055050403">"Correu electrònic"</string>
-    <string name="dial" msgid="4204975095406423102">"Truca"</string>
-    <string name="map" msgid="6068210738233985748">"Mapes"</string>
-    <string name="browse" msgid="6993590095938149861">"Navegador"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contacte"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"L\'espai d\'emmagatzematge s\'està esgotant"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"És possible que algunes funcions del sistema no funcionin"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"No hi ha prou espai d\'emmagatzematge per al sistema. Comprova que tinguis 250 MB d\'espai lliure i reinicia."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM no compatible"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telèfon no no compatible"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Finestra emergent"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> més"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c0760b1..1bc27616 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -176,8 +176,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Pracovní profil byl smazán, protože není k dispozici aplikace pro správu"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Aplikace pro správu pracovního profilu chybí nebo je poškozena. Váš pracovní profil a související data proto byla smazána. Požádejte o pomoc administrátora."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Váš pracovní profil v tomto zařízení již není k dispozici"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Příliš mnoho pokusů o zadání hesla"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Zařízení je spravováno"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Toto zařízení je spravováno vaší organizací, která může sledovat síťový provoz. Podrobnosti zobrazíte klepnutím."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Zařízení bude vymazáno"</string>
@@ -256,6 +255,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozornění"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Prodejní ukázka"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Připojení USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplikace je spuštěna"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikace spotřebovávají baterii"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> využívá baterii"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Aplikace (<xliff:g id="NUMBER">%1$d</xliff:g>) využívají baterii"</string>
@@ -1019,11 +1019,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Metoda zadávání dat"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operace s textem"</string>
     <string name="email" msgid="4560673117055050403">"Poslat e-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Mapy"</string>
-    <string name="browse" msgid="6993590095938149861">"Prohlížeč"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"V úložišti je málo místa"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Některé systémové funkce nemusí fungovat"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Pro systém není dostatek místa v úložišti. Uvolněte alespoň 250 MB místa a restartujte zařízení."</string>
@@ -1860,4 +1865,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM karta není povolena"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon není povolen"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Vyskakovací okno"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"a ještě <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 7b941b3..075aa26 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Arbejdsprofilen blev slettet, fordi der mangler en administrationsapp"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Administrationsappen til arbejdsprofilen mangler eller er beskadiget. Derfor er din arbejdsprofil og dine relaterede data blevet slettet. Kontakt din administrator for at få hjælp."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Din arbejdsprofil er ikke længere tilgængelig på denne enhed"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"For mange mislykkede adgangskodeforsøg"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Dette er en administreret enhed"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Din organisation administrerer denne enhed og kan overvåge netværkstrafik. Tryk for at se oplysninger."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Enheden slettes"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Underretninger"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo til udstilling i butik"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-forbindelse"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Appen kører"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps, der bruger batteri"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruger batteri"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps bruger batteri"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Inputmetode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Opkald"</string>
-    <string name="map" msgid="6068210738233985748">"Kort"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"Sms"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontaktperson"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der er snart ikke mere lagerplads"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Nogle systemfunktioner virker måske ikke"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Der er ikke nok ledig lagerplads til systemet. Sørg for, at du har 250 MB ledig plads, og genstart."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-kortet har ikke adgangstilladelse"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefonen har ikke adgangstilladelse"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Pop op-vindue"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> mere"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 68b0355..f6e13dd 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Arbeitsprofil aufgrund fehlender Admin-App gelöscht"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Die Admin-App für das Arbeitsprofil fehlt oder ist beschädigt. Daher wurden dein Arbeitsprofil und alle zugehörigen Daten gelöscht. Bitte wende dich für weitere Hilfe an deinen Administrator."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Dein Arbeitsprofil ist auf diesem Gerät nicht mehr verfügbar"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Zu viele falsche Passworteingaben"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Dies ist ein verwaltetes Gerät"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Deine Organisation verwaltet dieses Gerät und überprüft unter Umständen den Netzwerkverkehr. Tippe hier, um weitere Informationen zu erhalten."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Die Daten auf deinem Gerät werden gelöscht."</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Warnmeldungen"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo für Einzelhandel"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-Verbindung"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App wird ausgeführt"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Strom verbrauchende Apps"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> verbraucht Strom"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> Apps verbrauchen Strom"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Eingabemethode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaktionen"</string>
     <string name="email" msgid="4560673117055050403">"E-Mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Karten"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der Speicherplatz wird knapp"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Einige Systemfunktionen funktionieren möglicherweise nicht."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Der Speicherplatz reicht nicht für das System aus. Stelle sicher, dass 250 MB freier Speicherplatz vorhanden sind, und starte das Gerät dann neu."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-Karte nicht zulässig"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Smartphone nicht zulässig"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Pop-up-Fenster"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 9ca0a86..0992eae 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Το προφίλ εργασίας διαγράφηκε λόγω απουσίας της εφαρμογής διαχείρισης"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Η εφαρμογή διαχείρισης προφίλ εργασίας είτε λείπει είτε είναι κατεστραμμένη. Ως αποτέλεσμα, διαγράφηκε το προφίλ εργασίας και τα σχετικά δεδομένα. Επικοινωνήστε με τον διαχειριστή σας για βοήθεια."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Το προφίλ εργασίας σας δεν είναι πια διαθέσιμο σε αυτήν τη συσκευή"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Πάρα πολλές προσπάθειες εισαγωγής κωδικού πρόσβασης"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Η συσκευή είναι διαχειριζόμενη"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Ο οργανισμός σας διαχειρίζεται αυτήν τη συσκευή και ενδέχεται να παρακολουθεί την επισκεψιμότητα δικτύου. Πατήστε για λεπτομέρειες."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Η συσκευή σας θα διαγραφεί"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ειδοποιήσεις"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Επίδειξη λιανικής"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Σύνδεση USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Η εφαρμογή εκτελείται"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Εφαρμογές που καταναλώνουν μπαταρία"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> χρησιμοποιεί μπαταρία"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> εφαρμογές χρησιμοποιούν μπαταρία"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Μέθοδος εισόδου"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ενέργειες κειμένου"</string>
     <string name="email" msgid="4560673117055050403">"Ηλεκτρονικό ταχυδρομείο"</string>
-    <string name="dial" msgid="4204975095406423102">"Τηλέφωνο"</string>
-    <string name="map" msgid="6068210738233985748">"Χάρτες"</string>
-    <string name="browse" msgid="6993590095938149861">"Πρόγραμμα περιήγησης"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Επαφή"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ο αποθηκευτικός χώρος εξαντλείται"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Ορισμένες λειτουργίες συστήματος ενδέχεται να μην λειτουργούν"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Δεν υπάρχει αρκετός αποθηκευτικός χώρος για το σύστημα. Βεβαιωθείτε ότι διαθέτετε 250 MB ελεύθερου χώρου και κάντε επανεκκίνηση."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Η κάρτα SIM δεν επιτρέπεται"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Το τηλέφωνο δεν επιτρέπεται"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Αναδυόμενο παράθυρο"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 73e55da..07450b2 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App running"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps consuming battery"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Input method"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
-    <string name="dial" msgid="4204975095406423102">"Phone"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contact"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure that you have 250 MB of free space and restart."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM not allowed"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Phone not allowed"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Pop-Up Window"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 73e55da..07450b2 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App running"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps consuming battery"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Input method"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
-    <string name="dial" msgid="4204975095406423102">"Phone"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contact"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure that you have 250 MB of free space and restart."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM not allowed"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Phone not allowed"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Pop-Up Window"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 73e55da..07450b2 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App running"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps consuming battery"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Input method"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
-    <string name="dial" msgid="4204975095406423102">"Phone"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contact"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure that you have 250 MB of free space and restart."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM not allowed"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Phone not allowed"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Pop-Up Window"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 73e55da..07450b2 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App running"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps consuming battery"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Input method"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
-    <string name="dial" msgid="4204975095406423102">"Phone"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contact"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure that you have 250 MB of free space and restart."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM not allowed"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Phone not allowed"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Pop-Up Window"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index db7ab4f..336b35d 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‏‏‏‎‏‎Alerts‎‏‎‎‏‎"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎Retail demo‎‏‎‎‏‎"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎USB connection‎‏‎‎‏‎"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎App running‎‏‎‎‏‎"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‏‏‎‎Apps consuming battery‎‏‎‎‏‎"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is using battery‎‏‎‎‏‎"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="NUMBER">%1$d</xliff:g>‎‏‎‎‏‏‏‎ apps are using battery‎‏‎‎‏‎"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‏‏‎Input method‎‏‎‎‏‎"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‎Text actions‎‏‎‎‏‎"</string>
     <string name="email" msgid="4560673117055050403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎Email‎‏‎‎‏‎"</string>
-    <string name="dial" msgid="4204975095406423102">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎Phone‎‏‎‎‏‎"</string>
-    <string name="map" msgid="6068210738233985748">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‎Maps‎‏‎‎‏‎"</string>
-    <string name="browse" msgid="6993590095938149861">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‎‎‏‎‏‎Browser‎‏‎‎‏‎"</string>
-    <string name="sms" msgid="8250353543787396737">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎SMS‎‏‎‎‏‎"</string>
-    <string name="add_contact" msgid="7990645816259405444">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎Contact‎‏‎‎‏‎"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‎‎Storage space running out‎‏‎‎‏‎"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎Some system functions may not work‎‏‎‎‏‎"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎‎‎Not enough storage for the system. Make sure you have 250MB of free space and restart.‎‏‎‎‏‎"</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎SIM not allowed‎‏‎‎‏‎"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‏‎Phone not allowed‎‏‎‎‏‎"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎Popup Window‎‏‎‎‏‎"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎+ ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%1$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 16a43ba..96634e5 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo para punto de venta"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexión USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App en ejecución"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps que consumen batería"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> está consumiendo batería"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps están consumiendo batería"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
     <string name="email" msgid="4560673117055050403">"Correo electrónico"</string>
-    <string name="dial" msgid="4204975095406423102">"Teléfono"</string>
-    <string name="map" msgid="6068210738233985748">"Mapas"</string>
-    <string name="browse" msgid="6993590095938149861">"Navegador"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contacto"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio de almacenamiento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no estén disponibles."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"No hay espacio suficiente para el sistema. Asegúrate de que haya 250 MB libres y reinicia el dispositivo."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM no permitida"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Teléfono no permitido"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Ventana emergente"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> más"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 5827a97..9d94c7c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo para tiendas"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexión USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplicación en ejecución"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicaciones que consumen batería"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando la batería"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicaciones están usando la batería"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Método de introducción de texto"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
     <string name="email" msgid="4560673117055050403">"Correo electrónico"</string>
-    <string name="dial" msgid="4204975095406423102">"Teléfono"</string>
-    <string name="map" msgid="6068210738233985748">"Mapas"</string>
-    <string name="browse" msgid="6993590095938149861">"Navegador"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contacto"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no funcionen."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"No hay espacio suficiente para el sistema. Comprueba que haya 250 MB libres y reinicia el dispositivo."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM no compatible"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Teléfono no compatible"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Ventana emergente"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> más"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 1d40f4a..9f7ca2e 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Teatised"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Poedemo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-ühendus"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Rakendus töötab"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Rakendused kasutavad akutoidet"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> kasutab akutoidet"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> rakendust kasutab akutoidet"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Sisestusmeetod"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoimingud"</string>
     <string name="email" msgid="4560673117055050403">"E-post"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"Brauser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Talletusruum saab täis"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Mõned süsteemifunktsioonid ei pruugi töötada"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Süsteemis pole piisavalt talletusruumi. Veenduge, et seadmes oleks 250 MB vaba ruumi, ja käivitage seade uuesti."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-kaart pole lubatud"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon pole lubatud"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Hüpikaken"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index a864f94..1749a88 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Abisuak"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Saltzaileentzako demoa"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB konexioa"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplikazio bat abian da"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Bateria kontsumitzen ari diren aplikazioak"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ari da bateria erabiltzen"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikazio ari dira bateria erabiltzen"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Idazketa-metodoa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Testu-ekintzak"</string>
     <string name="email" msgid="4560673117055050403">"Posta"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefonoa"</string>
-    <string name="map" msgid="6068210738233985748">"Mapak"</string>
-    <string name="browse" msgid="6993590095938149861">"Arakatzailea"</string>
-    <string name="sms" msgid="8250353543787396737">"SMSa"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontaktua"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Memoria betetzen ari da"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Sistemaren funtzio batzuek ez dute agian funtzionatuko"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sisteman ez dago behar adina memoria. Ziurtatu gutxienez 250 MB erabilgarri dituzula eta, ondoren, berrabiarazi gailua."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Ez da onartzen SIM txartela"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Ez da onartzen telefonoa"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Leiho gainerakorra"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"Beste <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 77336ff..3fb613d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"به دلیل نداشتن برنامه سرپرست، نمایه کاری حذف شد"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"برنامه سرپرست نمایه کاری یا وجود ندارد یا خراب است. در نتیجه، نمایه کاری شما و داده‌های مرتبط با آن حذف شده است. برای دریافت راهنمایی با سرپرست سیستم تماس بگیرید."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"نمایه کاری شما دیگر در این دستگاه دردسترس نیست"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"تلاش‌های بسیار زیادی برای وارد کردن گذرواژه انجام شده است"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"دستگاه مدیریت می‌شود"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"سازمانتان این دستگاه را مدیریت می‌کند و ممکن است ترافیک شبکه را پایش کند. برای اطلاع از جزئیات، ضربه بزنید."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"دستگاهتان پاک خواهد شد"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"هشدارها"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"نمونه برای خرده‌فروشان"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"‏اتصال USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"برنامه درحال اجرا"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"برنامه‌های مصرف‌کننده باتری"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> درحال استفاده کردن از باتری است"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> برنامه درحال استفاده کردن از باتری هستند"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"روش ورودی"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"عملکردهای متنی"</string>
     <string name="email" msgid="4560673117055050403">"رایانامه"</string>
-    <string name="dial" msgid="4204975095406423102">"تلفن"</string>
-    <string name="map" msgid="6068210738233985748">"نقشه‌ها"</string>
-    <string name="browse" msgid="6993590095938149861">"مرورگر"</string>
-    <string name="sms" msgid="8250353543787396737">"پیامک"</string>
-    <string name="add_contact" msgid="7990645816259405444">"مخاطب"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"حافظه درحال پر شدن است"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"برخی از عملکردهای سیستم ممکن است کار نکنند"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"فضای ذخیره‌سازی سیستم کافی نیست. اطمینان حاصل کنید که دارای ۲۵۰ مگابایت فضای خالی هستید و سیستم را راه‌اندازی مجدد کنید."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"سیم‌کارت مجاز نیست"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"تلفن مجاز نیست"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"پنجره بازشو"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"‎+ <xliff:g id="NUMBER">%1$d</xliff:g>‎"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 0c4e883..c884100 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ilmoitukset"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Esittelytila"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-yhteys"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Sovellus käynnissä"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Akkua kuluttavat sovellukset"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> käyttää akkua."</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> sovellusta käyttää akkua."</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Syöttötapa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoiminnot"</string>
     <string name="email" msgid="4560673117055050403">"Sähköposti"</string>
-    <string name="dial" msgid="4204975095406423102">"Puhelin"</string>
-    <string name="map" msgid="6068210738233985748">"Kartat"</string>
-    <string name="browse" msgid="6993590095938149861">"Selain"</string>
-    <string name="sms" msgid="8250353543787396737">"Tekstiviesti"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Yhteystieto"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Tallennustila loppumassa"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Kaikki järjestelmätoiminnot eivät välttämättä toimi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Tallennustila ei riitä. Varmista, että vapaata tilaa on 250 Mt, ja käynnistä uudelleen."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-kortti estetty"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Puhelin estetty"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Ponnahdusikkuna"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index a8ab142..cd3cc3b 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Profil professionnel supprimé en raison de l\'application d\'administration manquante"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Le profil professionnel de l\'application d\'administration est manquant ou corrompu. Votre profil professionnel et ses données connexes ont donc été supprimés. Communiquez avec votre administrateur pour obtenir de l\'assistance."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Votre profil professionnel n\'est plus accessible sur cet appareil"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Trop de tentatives d\'entrée du mot de passe"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"L\'appareil est géré"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Touchez ici pour obtenir plus d\'information."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Le contenu de votre appareil sera effacé"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Démo en magasin"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connexion USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Application en cours d\'exécution"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Applications qui sollicitent la pile"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> sollicite la pile"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> applications sollicitent la pile"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Mode de saisie"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string>
     <string name="email" msgid="4560673117055050403">"Courriel"</string>
-    <string name="dial" msgid="4204975095406423102">"Téléphone"</string>
-    <string name="map" msgid="6068210738233985748">"Cartes"</string>
-    <string name="browse" msgid="6993590095938149861">"Navigateur"</string>
-    <string name="sms" msgid="8250353543787396737">"Messagerie texte"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contact"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Espace de stockage bientôt saturé"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Il est possible que certaines fonctionnalités du système ne soient pas opérationnelles."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Espace de stockage insuffisant pour le système. Assurez-vous de disposer de 250 Mo d\'espace libre, puis redémarrez."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Carte SIM non autorisée"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Téléphone non autorisé"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Fenêtre contextuelle"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 4c2bcca..615402e 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Démonstration en magasin"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connexion USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Application en cours d\'exécution"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Applications utilisant la batterie"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> utilise la batterie"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> applications utilisent la batterie"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Mode de saisie"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Téléphone"</string>
-    <string name="map" msgid="6068210738233985748">"Cartes"</string>
-    <string name="browse" msgid="6993590095938149861">"Navigateur"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contact"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Espace de stockage bientôt saturé"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Il est possible que certaines fonctionnalités du système ne soient pas opérationnelles."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Espace de stockage insuffisant pour le système. Assurez-vous de disposer de 250 Mo d\'espace libre, puis redémarrez."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Carte SIM non autorisée"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Téléphone non autorisé"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Fenêtre pop-up"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> autres"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 12cbbb3..22dafe8 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Eliminouse o perfil de traballo porque falta a aplicación de administración"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Falta a aplicación de administración do perfil de traballo ou ben está danada. Como resultado, eliminouse o teu perfil de traballo e os datos relacionados. Para obter asistencia, contacta co administrador."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"O teu perfil de traballo xa non está dispoñible neste dispositivo"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Demasiados intentos de introdución do contrasinal"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"O dispositivo está xestionado"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"A túa organización xestiona este dispositivo e pode controlar o tráfico de rede. Toca para obter máis detalles."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Borrarase o teu dispositivo"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demostración comercial"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"conexión USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Estase executando a aplicación"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicacións que consumen batería"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo batería"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacións están consumindo batería"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Accións de texto"</string>
     <string name="email" msgid="4560673117055050403">"Correo electrónico"</string>
-    <string name="dial" msgid="4204975095406423102">"Teléfono"</string>
-    <string name="map" msgid="6068210738233985748">"Mapas"</string>
-    <string name="browse" msgid="6993590095938149861">"Navegador"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contacto"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Estase esgotando o espazo de almacenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"É posible que algunhas funcións do sistema non funcionen"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Non hai almacenamento suficiente para o sistema. Asegúrate de ter un espazo libre de 250 MB e reinicia o dispositivo."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Non se admite a tarxeta SIM"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Non se admite o teléfono"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Ventá emerxente"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> máis"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 4cb735d..cb9bb46 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"ખૂટતી વ્યવસ્થાપક ઍપ્લિકેશનને કારણે કાર્યાલયની પ્રોફાઇલ કાઢી નાખી"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"કાર્ય પ્રોફાઇલ વ્યવસ્થાપક ઍપ્લિકેશન ખૂટે છે અથવા તો દૂષિત છે. પરિણામે, તમારી કાર્યાલયની પ્રોફાઇલ અને તે સંબંધિત ડેટા કાઢી નાખવામાં આવ્યો છે. સહાયતા માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"આ ઉપકરણ પર તમારી કાર્યાલયની પ્રોફાઇલ હવે ઉપલબ્ધ નથી"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"પાસવર્ડના ઘણા વધુ પ્રયત્નો"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ઉપકરણ સંચાલિત છે"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"તમારી સંસ્થા આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિફનું નિયમન કરી શકે છે. વિગતો માટે ટૅપ કરો."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"તમારું ઉપકરણ કાઢી નાખવામાં આવશે"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ચેતવણીઓ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"રિટેલ ડેમો"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB કનેક્શન"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ઍપ બૅટરીનો વપરાશ કરી રહ્યાં છે"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> બૅટરીનો ઉપયોગ કરી રહ્યું છે"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ઍપ બૅટરીનો ઉપયોગ કરી રહ્યાં છે"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ઇનપુટ પદ્ધતિ"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ટેક્સ્ટ ક્રિયાઓ"</string>
     <string name="email" msgid="4560673117055050403">"ઇમેઇલ"</string>
-    <string name="dial" msgid="4204975095406423102">"ફોન"</string>
-    <string name="map" msgid="6068210738233985748">"નકશા"</string>
-    <string name="browse" msgid="6993590095938149861">"બ્રાઉઝર"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"સંપર્ક"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"સ્ટોરેજ સ્થાન સમાપ્ત થયું"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"કેટલાક સિસ્ટમ કાર્યો કામ કરી શકશે નહીં"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"સિસ્ટમ માટે પર્યાપ્ત સ્ટોરેજ નથી. ખાતરી કરો કે તમારી પાસે 250MB ખાલી સ્થાન છે અને ફરીથી પ્રારંભ કરો."</string>
@@ -1790,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"સિમ મંજૂર નથી"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ફોન મંજૂર નથી"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"પૉપઅપ વિંડો"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 3e37771..6b9c2306 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"अनुपलब्ध व्यवस्थापक ऐप्लिकेशन के कारण कार्य प्रोफ़ाइल हटा दी गई"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"कार्य प्रोफ़ाइल व्यवस्थापक ऐप्लिकेशन या तो मौजूद नहीं है या वह खराब हो गया है. परिणामस्वरूप, आपकी कार्य प्रोफ़ाइल और उससे जुड़े डेटा को हटा दिया गया है. सहायता के लिए अपने व्यवस्थापक से संपर्क करें."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"आपकी कार्य प्रोफ़ाइल अब इस डिवाइस पर उपलब्‍ध नहीं है"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"कई बार गलत पासवर्ड डाला गया"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"डिवाइस प्रबंधित है"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"आपका संगठन इस डिवाइस का प्रबंधन करता है और वह नेटवर्क ट्रैफ़िक की निगरानी भी कर सकता है. विवरण के लिए टैप करें."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"आपके डिवाइस को मिटा दिया जाएगा"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"सूचनाएं"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"खुदरा डेमो"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB कनेक्शन"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"बैटरी की खपत करने वाले ऐप"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> बैटरी का इस्तेमाल कर रहा है"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ऐप बैटरी का इस्तेमाल कर रहे हैं"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"इनपुट विधि"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"लेख क्रियाएं"</string>
     <string name="email" msgid="4560673117055050403">"ईमेल करें"</string>
-    <string name="dial" msgid="4204975095406423102">"फ़ोन"</string>
-    <string name="map" msgid="6068210738233985748">"मानचित्र"</string>
-    <string name="browse" msgid="6993590095938149861">"ब्राउज़र"</string>
-    <string name="sms" msgid="8250353543787396737">"मैसेज (एसएमएस)"</string>
-    <string name="add_contact" msgid="7990645816259405444">"संपर्क"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"मेमोरी में जगह नहीं बची है"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"हो सकता है कुछ सिस्टम फ़ंक्शन कार्य न करें"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"सिस्टम के लिए ज़रूरी मेमोरी नहीं है. पक्का करें कि आपके पास 250एमबी की खाली जगह है और फिर से शुरू करें."</string>
@@ -1790,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM की अनुमति नहीं है"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"फ़ोन की अनुमति नहीं है"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"पॉपअप विंडो"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3c295c8..46f6647 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -174,8 +174,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Radni je profil izbrisan jer nedostaje administratorska aplikacija"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Administratorska aplikacija radnog profila nedostaje ili je oštećena. Zbog toga su radni profil i povezani podaci izbrisani. Za pomoć se obratite svom administratoru."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Vaš radni profil više nije dostupan na ovom uređaju"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Previše pokušaja unosa zaporke"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Uređaj je upravljan"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Vaša organizacija upravlja ovim uređajem i može nadzirati mrežni promet. Dodirnite za pojedinosti."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će se izbrisati"</string>
@@ -253,6 +252,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Prodajni demo-način"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Izvodi se aplikacija"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacije troše bateriju"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Broj aplikacija koje koriste bateriju: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
@@ -999,11 +999,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje s tekstom"</string>
     <string name="email" msgid="4560673117055050403">"E-pošta"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Karte"</string>
-    <string name="browse" msgid="6993590095938149861">"Preglednik"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke sistemske funkcije možda neće raditi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno pohrane za sustav. Oslobodite 250 MB prostora i pokrenite uređaj ponovo."</string>
@@ -1825,4 +1830,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM nije dopušten"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon nije dopušten"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Skočni prozor"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"još <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 4e8d03c..a25b0d4 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"A munkaprofilt a rendszer hiányzó rendszergazdai alkalmazás miatt törölte"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"A munkaprofil rendszergazdai alkalmazása hiányzik vagy sérült. A rendszer ezért törölte a munkaprofilt, és az ahhoz kapcsolódó adatokat. Ha segítségre van szüksége, vegye fel a kapcsolatot rendszergazdájával."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Munkaprofilja már nem hozzáférhető ezen az eszközön."</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Túl sok jelszómegadási kísérlet"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Felügyelt eszköz"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Ezt az eszközt szervezete kezeli, és lehetséges, hogy a hálózati forgalmat is figyelik. További részletekért koppintson."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"A rendszer törölni fogja eszközét"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Értesítések"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kiskereskedelmi bemutató"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-kapcsolat"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Jelenleg futó alkalmazás"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Akkumulátort használó alkalmazások"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás használja az akkumulátort"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> alkalmazás használja az akkumulátort"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Beviteli mód"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Műveletek szöveggel"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Térkép"</string>
-    <string name="browse" msgid="6993590095938149861">"Böngésző"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Névjegy"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Kevés a szabad terület"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Előfordulhat, hogy néhány rendszerfunkció nem működik."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nincs elegendő tárhely a rendszerhez. Győződjön meg arról, hogy rendelkezik 250 MB szabad területtel, majd kezdje elölről."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"A SIM-kártya nem engedélyezett"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"A telefon nem engedélyezett"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Előugró ablak"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index a5fbe34f..3eb61e4 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ծանուցումներ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Խանութի ցուցադրական ռեժիմ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB կապակցում"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Հավելվածն աշխատում է"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Մարտկոցի լիցքը ծախսող հավելվածներ"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"«<xliff:g id="APP_NAME">%1$s</xliff:g>» հավելվածը ծախսում է մարտկոցի լիցքը"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> հավելված ծախսում է մարտկոցի լիցքը"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Մուտքագրման եղանակը"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Տեքստի գործողությունները"</string>
     <string name="email" msgid="4560673117055050403">"Էլփոստ"</string>
-    <string name="dial" msgid="4204975095406423102">"Հեռախոս"</string>
-    <string name="map" msgid="6068210738233985748">"Քարտեզներ"</string>
-    <string name="browse" msgid="6993590095938149861">"Դիտարկիչ"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Կոնտակտ"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Հիշողությունը սպառվում է"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Որոշ գործառույթներ կարող են չաշխատել"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Համակարգի համար բավարար հիշողություն չկա: Համոզվեք, որ ունեք 250ՄԲ ազատ տարածություն և վերագործարկեք:"</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM քարտի օգտագործումն արգելված է"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Հեռախոսի օգտագործումն արգելված է"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Հայտնվող պատուհան"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 173ad40..433ae8b 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Notifikasi"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo promo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Sambungan USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplikasi berjalan"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikasi yang menggunakan baterai"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang menggunakan baterai"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikasi sedang meggunakan baterai"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Metode masukan"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
-    <string name="dial" msgid="4204975095406423102">"Telepon"</string>
-    <string name="map" msgid="6068210738233985748">"Peta"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontak"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang penyimpanan hampir habis"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak dapat bekerja"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Penyimpanan tidak cukup untuk sistem. Pastikan Anda memiliki 250 MB ruang kosong, lalu mulai ulang."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM tidak diizinkan"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Ponsel tidak diizinkan"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Jendela Pop-up"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index c61c26e..17112a2 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Vinnusniði eytt vegna þess að stjórnunarforrit vantar"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Stjórnunarforrit vinnusniðsins vantar eða er skemmt. Vinnusniðinu og gögnum því tengdu hefur því verið eytt. Hafðu samband við kerfisstjórann til að fá frekari aðstoð."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Vinnusniðið þitt er ekki lengur í boði á þessu tæki"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Of margar tilraunir til að slá inn aðgangsorð"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Tækinu er stjórnað"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Fyrirtækið þitt stjórnar þessu tæki og kann að fylgjast með netnotkun. Ýttu hér til að fá upplýsingar."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Tækið verður hreinsað"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Tilkynningar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kynningarútgáfa fyrir verslanir"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-tenging"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Forrit er í gangi"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Forrit sem nota rafhlöðuorku"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> notar rafhlöðuorku"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> forrit nota rafhlöðuorku"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Innsláttaraðferð"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaaðgerðir"</string>
     <string name="email" msgid="4560673117055050403">"Tölvupóstur"</string>
-    <string name="dial" msgid="4204975095406423102">"Sími"</string>
-    <string name="map" msgid="6068210738233985748">"Kort"</string>
-    <string name="browse" msgid="6993590095938149861">"Vafri"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS-skilaboð"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Tengiliður"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Geymslurýmið er senn á þrotum"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Sumir kerfiseiginleikar kunna að vera óvirkir"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Ekki nægt geymslurými fyrir kerfið. Gakktu úr skugga um að 250 MB séu laus og endurræstu."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-kort er ekki leyft"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Sími er ekki leyfður"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Sprettigluggi"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 7e54a9c7..54d9dc8 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Avvisi"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo retail"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connessione USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App in esecuzione"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"App che consumano la batteria"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> sta consumando la batteria"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> app stanno consumando la batteria"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Metodo inserimento"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Azioni testo"</string>
     <string name="email" msgid="4560673117055050403">"Invia una email"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefono"</string>
-    <string name="map" msgid="6068210738233985748">"Mappe"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contatto"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Spazio di archiviazione in esaurimento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Alcune funzioni di sistema potrebbero non funzionare"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Memoria insufficiente per il sistema. Assicurati di avere 250 MB di spazio libero e riavvia."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Scheda SIM non consentita"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefono non consentito"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Finestra popup"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 23b8e38..56d88f0 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -176,8 +176,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"פרופיל העבודה נמחק מפני שחסרה אפליקציית ניהול"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"אפליקציית הניהול של פרופיל העבודה חסרה או פגומה. כתוצאה מכך, פרופיל העבודה שלך נמחק, כולל כל הנתונים הקשורים אליו. לקבלת עזרה, פנה למנהל המערכת."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"פרופיל העבודה שלך אינו זמין עוד במכשיר הזה"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"בוצעו ניסיונות רבים מדי להזנת סיסמה"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"המכשיר מנוהל"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"הארגון שלך מנהל מכשיר זה ועשוי לנטר את התנועה ברשת. הקש לקבלת פרטים."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"תתבצע מחיקה של המכשיר"</string>
@@ -256,6 +255,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"התראות"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"הדגמה לקמעונאים"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"‏חיבור USB"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"אפליקציות שמרוקנות את הסוללה"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> משתמשת בסוללה"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> אפליקציות משתמשות בסוללה"</string>
@@ -1019,11 +1020,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"שיטת קלט"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"פעולות טקסט"</string>
     <string name="email" msgid="4560673117055050403">"אימייל"</string>
-    <string name="dial" msgid="4204975095406423102">"טלפון"</string>
-    <string name="map" msgid="6068210738233985748">"מפות"</string>
-    <string name="browse" msgid="6993590095938149861">"דפדפן"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"איש קשר"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"שטח האחסון אוזל"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ייתכן שפונקציות מערכת מסוימות לא יפעלו"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"‏אין מספיק שטח אחסון עבור המערכת. ודא שיש לך שטח פנוי בגודל 250MB התחל שוב."</string>
@@ -1860,4 +1866,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"‏כרטיס ה-SIM לא מורשה"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"הטלפון לא מורשה"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"חלון קופץ"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 2100470..affe195 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"管理アプリがないため仕事用プロファイルが削除されました"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"仕事用プロファイルの管理アプリがないか、破損しています。そのため仕事用プロファイルと関連データが削除されました。管理者にサポートをご依頼ください。"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"お使いの仕事用プロファイルはこの端末で使用できなくなりました"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"パスワード入力回数が上限を超えました"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"管理対象の端末"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"この端末は組織によって管理され、ネットワーク トラフィックが監視される場合があります。詳しくはタップしてください。"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"端末のデータが消去されます"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"通知"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"販売店デモ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 接続"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"アプリを実行しています"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"アプリが電池を消費しています"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」が電池を使用しています"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> 個のアプリが電池を使用しています"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"入力方法"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"テキスト操作"</string>
     <string name="email" msgid="4560673117055050403">"メール"</string>
-    <string name="dial" msgid="4204975095406423102">"電話"</string>
-    <string name="map" msgid="6068210738233985748">"マップ"</string>
-    <string name="browse" msgid="6993590095938149861">"ブラウザ"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"連絡先"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"空き容量わずか"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"一部のシステム機能が動作しない可能性があります"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"システムに十分な容量がありません。250MBの空き容量を確保して再起動してください。"</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM は許可されていません"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"電話は許可されていません"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"ポップアップ ウィンドウ"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"他 <xliff:g id="NUMBER">%1$d</xliff:g> 件"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index ee8daad..c85b70e 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"გაფრთხილებები"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"დემო-რეჟიმი საცალო მოვაჭრეებისთვის"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB კავშირი"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"აპი გაშვებულია"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ბატარეის მხარჯავი აპები"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> იყენებს ბატარეას"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"ბატარეას <xliff:g id="NUMBER">%1$d</xliff:g> აპი იყენებს"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"შეყვანის მეთოდი"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ქმედებები ტექსტზე"</string>
     <string name="email" msgid="4560673117055050403">"ელფოსტა"</string>
-    <string name="dial" msgid="4204975095406423102">"ტელეფონი"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"ბრაუზერი"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"კონტაქტი"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"თავისუფალი ადგილი იწურება"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"სისტემის ზოგიერთმა ფუნქციამ შესაძლოა არ იმუშავოს"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"სისტემისათვის საკმარისი საცავი არ არის. დარწმუნდით, რომ იქონიოთ სულ მცირე 250 მბაიტი თავისუფალი სივრცე და დაიწყეთ ხელახლა."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM ბარათი დაუშვებელია"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ტელეფონი დაუშვებელია"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"ამომხტარი ფანჯარა"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index bbf1b4a9..5c34ef4 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Әкімші қолданбасы болмағандықтан жұмыс профилі жойылды"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Жұмыс профилінің әкімші қолданбасы жоқ немесе бүлінген. Нәтижесінде жұмыс профиліңіз және қатысты деректер жойылды. Көмек алу үшін әкімшіге хабарласыңыз."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Жұмыс профиліңіз осы құрылғыда енді қолжетімді емес"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Құпия сөз көп рет қате енгізілді"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Құрылғы басқарылады"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін. Мәліметтер алу үшін түртіңіз."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Құрылғыңыздағы деректер өшіріледі"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Дабылдар"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Бөлшек саудаға арналған демо нұсқасы"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB байланысы"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Қолданба қосулы"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Батареяны пайдаланып жатқан қолданбалар"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> батареяны пайдалануда"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> қолданба батареяны пайдалануда"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Енгізу әдісі"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Мәтін әрекеттері"</string>
     <string name="email" msgid="4560673117055050403">"Электрондық пошта"</string>
-    <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"Браузер"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Контакт"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Жадта орын азайып барады"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Жүйенің кейбір функциялары жұмыс істемеуі мүмкін"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Жүйе үшін жад жеткіліксіз. 250 МБ бос орын бар екенін тексеріп, қайта іске қосыңыз."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM картасына рұқсат етілмеген"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Телефонға рұқсат етілмеген"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Қалқымалы терезе"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 128c3f3..bdd87d3 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"កម្រងព័ត៌មាន​ការងារ​ត្រូវបាន​លុប​ដោយសារ​បាត់​កម្មវិធី​អ្នកគ្រប់គ្រង"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"កម្មវិធី​អ្នកគ្រប់គ្រង​កម្រងព័ត៌មាន​ការងារនេះ​អាច​បាត់ ឬ​មាន​បញ្ហា។ ដូច្នេះហើយ​ទើប​កម្រងព័ត៌មាន​ការងារ​របស់អ្នក និង​ទិន្នន័យ​ដែល​ពាក់ព័ន្ធត្រូវ​បានលុប។ សូមទាក់ទង​ទៅអ្នក​គ្រប់គ្រង​របស់អ្នក ដើម្បី​ទទួល​បាន​ជំនួយ។"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"កម្រងព័ត៌មាន​ការងារ​របស់អ្នក​លែងមាន​នៅលើ​ឧបករណ៍​នេះទៀត​ហើយ"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"ការព្យាយាមបញ្ចូលពាក្យសម្ងាត់ច្រើនដងពេកហើយ"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ឧបករណ៍ស្ថិតក្រោមការគ្រប់គ្រង"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"ស្ថាប័នរបស់អ្នកគ្រប់គ្រងឧបករណ៍នេះ ហើយអាចនឹងតាមដានចរាចរណ៍បណ្តាញ។ ចុចដើម្បីទទួលបានព័ត៌មានលម្អិត។"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"ឧបករណ៍របស់អ្នកនឹងត្រូវបានលុប"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ការ​ជូនដំណឹង"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"របៀបដាក់បង្ហាញក្នុងហាង"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"ការ​តភ្ជាប់ USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"កម្មវិធី​ដែល​កំពុង​ដំណើរការ"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"កម្មវិធីដែល​កំពុងប្រើថ្ម"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងប្រើថ្ម"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"កម្មវិធីចំនួន <xliff:g id="NUMBER">%1$d</xliff:g> កំពុងប្រើថ្ម"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"វិធីសាស្ត្រ​បញ្ចូល"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"សកម្មភាព​អត្ថបទ"</string>
     <string name="email" msgid="4560673117055050403">"អ៊ីមែល"</string>
-    <string name="dial" msgid="4204975095406423102">"ទូរសព្ទ"</string>
-    <string name="map" msgid="6068210738233985748">"ផែនទី"</string>
-    <string name="browse" msgid="6993590095938149861">"កម្មវិធីរុករកតាមអ៊ីនធឺណិត"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"ទំនាក់​ទំនង"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"អស់​ទំហំ​ផ្ទុក"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារ​ប្រព័ន្ធ​មួយ​ចំនួន​អាច​មិន​ដំណើរការ​"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"មិន​មាន​ទំហំ​ផ្ទុក​​គ្រប់​គ្រាន់​សម្រាប់​ប្រព័ន្ធ​។ សូម​ប្រាកដ​ថា​អ្នក​មាន​ទំហំ​ទំនេរ​ 250MB ហើយ​ចាប់ផ្ដើម​ឡើង​វិញ។"</string>
@@ -1792,4 +1797,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"មិន​អនុញ្ញាត​ចំពោះសីុម​ទេ"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"មិន​អនុញ្ញាត​ចំពោះទូរសព្ទ​ទេ"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"វិនដូលេចឡើង"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index eaeb25b..fb0db1c 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"ನಿರ್ವಾಹಕ ಅಪ್ಲಿಕೇಶನ್‌ ತಪ್ಪಿಹೋಗಿರುವುದರಿಂದ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು ಅಳಿಸಲಾಗಿದೆ"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ನಿರ್ವಾಹಕ ಅಪ್ಲಿಕೇಶನ್ ಕಳೆದು ಹೋಗಿದೆ ಅಥವಾ ಹಾಳಾಗಿದೆ. ಇದರ ಪರಿಣಾಮವಾಗಿ ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಮತ್ತು ಅದಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಸಹಾಯಕ್ಕಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಈ ಸಾಧನದಲ್ಲಿ ಈಗ ಲಭ್ಯವಿಲ್ಲ"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"ಹಲವಾರು ಪಾಸ್‌ವರ್ಡ್ ಪ್ರಯತ್ನಗಳು"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಮೇಲೆ ಗಮನವಿರಿಸಬಹುದು. ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ಎಚ್ಚರಿಕೆಗಳು"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ರಿಟೇಲ್ ಡೆಮೋ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB ಸಂಪರ್ಕ"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಬ್ಯಾಟರಿಯನ್ನು ಉಪಯೋಗಿಸುತ್ತಿವೆ"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಬಳಸುತ್ತಿದೆ"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಬ್ಯಾಟರಿ ಬಳಸುತ್ತಿವೆ"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ಇನ್‌ಪುಟ್ ವಿಧಾನ"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ಪಠ್ಯದ ಕ್ರಮಗಳು"</string>
     <string name="email" msgid="4560673117055050403">"ಇಮೇಲ್"</string>
-    <string name="dial" msgid="4204975095406423102">"ಫೋನ್"</string>
-    <string name="map" msgid="6068210738233985748">"ನಕ್ಷೆಗಳು"</string>
-    <string name="browse" msgid="6993590095938149861">"ಬ್ರೌಸರ್"</string>
-    <string name="sms" msgid="8250353543787396737">"ಎಸ್‌ಎಂಎಸ್‌"</string>
-    <string name="add_contact" msgid="7990645816259405444">"ಸಂಪರ್ಕ"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ಸಂಗ್ರಹಣೆ ಸ್ಥಳವು ತುಂಬಿದೆ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ಕೆಲವು ಸಿಸ್ಟಂ ಕಾರ್ಯವಿಧಾನಗಳು ಕಾರ್ಯನಿರ್ವಹಿಸದೇ ಇರಬಹುದು"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ಸಿಸ್ಟಂನಲ್ಲಿ ಸಾಕಷ್ಟು ಸಂಗ್ರಹಣೆಯಿಲ್ಲ. ನೀವು 250MB ನಷ್ಟು ಖಾಲಿ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುವಿರಾ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ ಹಾಗೂ ಮರುಪ್ರಾರಂಭಿಸಿ."</string>
@@ -1790,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"ಸಿಮ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ಫೋನ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"ಪಾಪ್‌ಅಪ್ ವಿಂಡೋ"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 59fa0bf..a714be4 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"관리 앱이 없어서 직장 프로필이 삭제되었습니다."</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"직장 프로필 관리 앱이 없거나 손상되어 직장 프로필 및 관련 데이터가 삭제되었습니다. 도움이 필요한 경우 관리자에게 문의하세요."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"직장 프로필을 이 기기에서 더 이상 사용할 수 없습니다."</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"비밀번호 입력을 너무 많이 시도함"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"관리되는 기기"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"조직에서 이 기기를 관리하며 네트워크 트래픽을 모니터링할 수도 있습니다. 자세한 내용을 보려면 탭하세요."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"기기가 삭제됩니다."</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"알림"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"소매 데모"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 연결"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"실행 중인 앱"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"배터리를 소모하는 앱"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 배터리 사용 중"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"앱 <xliff:g id="NUMBER">%1$d</xliff:g>개에서 배터리 사용 중"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"입력 방법"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"텍스트 작업"</string>
     <string name="email" msgid="4560673117055050403">"이메일"</string>
-    <string name="dial" msgid="4204975095406423102">"전화"</string>
-    <string name="map" msgid="6068210738233985748">"지도"</string>
-    <string name="browse" msgid="6993590095938149861">"브라우저"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"연락처"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"저장 공간이 부족함"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"일부 시스템 기능이 작동하지 않을 수 있습니다."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"시스템의 저장 공간이 부족합니다. 250MB의 여유 공간이 확보한 후 다시 시작하세요."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM이 허용되지 않음"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"전화가 허용되지 않음"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"팝업 창"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g>개 더보기"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index fb7b4f6..e3afe8f 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Башкаруучу колдонмосу болбогондуктан, жумуш профили жок кылынды"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Жумуш профилинин башкаруучу колдонмосу жок же бузулгандыктан, жумуш профилиңиз жана ага байланыштуу дайындар жок кылынды. Жардам алуу үчүн администраторуңузга кайрылыңыз."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Жумуш профилиңиз бул түзмөктөн жок кылынды"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Өтө көп жолу сырсөздү киргизүү аракети жасалды"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Түзмөктү ишкана башкарат"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Ишканаңыз бул түзмөктү башкарат жана тармак трафигин көзөмөлдөшү мүмкүн. Чоо-жайын көрүү үчүн таптап коюңуз."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Түзмөгүңүз тазаланат"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Эскертүүлөр"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Чекене соода дүкөнү үчүн демо режим"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB аркылуу туташуу"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Колдонмо иштеп жатат"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Колдонмолор батареяңызды коротууда"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу батареяны пайдаланып жатат"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> колдонмо батареяны пайдаланып жатат"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Киргизүү ыкмасы"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Текст боюнча иштер"</string>
     <string name="email" msgid="4560673117055050403">"Электрондук почта"</string>
-    <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="6068210738233985748">"Карталар"</string>
-    <string name="browse" msgid="6993590095938149861">"Серепчи"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Байланыш"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Сактагычта орун калбай баратат"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Системанын кээ бир функциялары иштебеши мүмкүн"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Тутумда сактагыч жетишсиз. 250МБ бош орун бар экенин текшерип туруп, өчүрүп күйгүзүңүз."</string>
@@ -1791,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM картаны колдонууга тыюу салынган"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Телефонду колдонууга тыюу салынган"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Калкып чыкма терезе"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 477fbdc06..79a41aa 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ການເຕືອນ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ເດໂມສຳລັບຮ້ານຂາຍ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"ການເຊື່ອມຕໍ່ USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"ແອັບກຳລັງເຮັດວຽກ"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ແອັບທີ່ກຳລັງໃຊ້ແບັດເຕີຣີ"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງໃຊ້ແບັດເຕີຣີຢູ່"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ແອັບກຳລັງໃຊ້ແບັດເຕີຣີຢູ່"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ການເຮັດວຽກຂອງຂໍ້ຄວາມ"</string>
     <string name="email" msgid="4560673117055050403">"ອີເມວ"</string>
-    <string name="dial" msgid="4204975095406423102">"ໂທລະສັບ"</string>
-    <string name="map" msgid="6068210738233985748">"ແຜນທີ່"</string>
-    <string name="browse" msgid="6993590095938149861">"ໂປຣແກຣມທ່ອງເວັບ"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"ຕິດຕໍ່"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນກຳລັງຈະເຕັມ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ການເຮັດວຽກບາງຢ່າງຂອງລະບົບບາງອາດຈະໃຊ້ບໍ່ໄດ້"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"​ບໍ່​ມີ​ບ່ອນ​ເກັບ​ຂໍ້​ມູນ​ພຽງ​ພໍ​ສຳ​ລັບ​ລະ​ບົບ. ກວດ​ສອບ​ໃຫ້​ແນ່​ໃຈ​ວ່າ​ທ່ານ​ມີ​ພື້ນ​ທີ່​ຫວ່າງ​ຢ່າງ​ໜ້ອຍ 250MB ​ແລ້ວລອງ​ໃໝ່."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ SIM"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"ໜ້າຈໍປັອບອັບ"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 2e44ed2..e2a8412 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -176,8 +176,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Darbo profilis ištrintas dėl trūkstamos administratoriaus programos"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Trūksta darbo profilio administratoriaus programos arba ji sugadinta. Todėl darbo profilis ir susiję duomenys buvo ištrinti. Jei reikia pagalbos, susisiekite su administratoriumi."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Darbo profilis nebepasiekiamas šiame įrenginyje"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Per daug slaptažodžio bandymų"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Įrenginys yra tvarkomas"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Šį įrenginį tvarko organizacija ir gali stebėti tinklo srautą. Palieskite, kad gautumėte daugiau informacijos."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Įrenginys bus ištrintas"</string>
@@ -256,6 +255,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Įspėjimai"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstracinė versija mažmenininkams"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB jungtis"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Programa paleista"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Programos, naudojančios akumuliatoriaus energiją"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ naudoja akumuliatoriaus energiją"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Programų, naudojančių akumuliatoriaus energiją: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
@@ -1019,11 +1019,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Įvesties būdas"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksto veiksmai"</string>
     <string name="email" msgid="4560673117055050403">"Siųsti el. laišką"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefonas"</string>
-    <string name="map" msgid="6068210738233985748">"Žemėlapiai"</string>
-    <string name="browse" msgid="6993590095938149861">"Naršyklė"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontaktas"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Mažėja laisvos saugyklos vietos"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Kai kurios sistemos funkcijos gali neveikti"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sistemos saugykloje nepakanka vietos. Įsitikinkite, kad yra 250 MB laisvos vietos, ir paleiskite iš naujo."</string>
@@ -1860,4 +1865,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM kortelė neleidžiama"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefonas neleidžiamas"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Iššokantysis langas"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"Dar <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 659c9a7..bde2bf1 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -174,8 +174,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Darba profils tika dzēsts, jo trūkst administratora lietotnes."</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Trūkst darba profila administratora lietotnes, vai šī lietotne ir bojāta. Šī iemesla dēļ jūsu darba profils un saistītie dati tika dzēsti. Lai saņemtu palīdzību, sazinieties ar administratoru."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Jūsu darba profils šai ierīcē vairs nav pieejams."</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Veikts pārāk daudz paroles ievadīšanas mēģinājumu."</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Ierīce tiek pārvaldīta"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Jūsu organizācija pārvalda šo ierīci un var uzraudzīt tīkla datplūsmu. Pieskarieties, lai saņemtu detalizētu informāciju."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Jūsu ierīces dati tiks dzēsti"</string>
@@ -253,6 +252,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Brīdinājumi"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstrācijas versija veikaliem"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB savienojums"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Lietotne darbojas"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Lietotnes, kas patērē akumulatora jaudu"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> izmanto akumulatoru"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> lietotne(-es) izmanto akumulatoru"</string>
@@ -999,11 +999,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Ievades metode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksta darbības"</string>
     <string name="email" msgid="4560673117055050403">"E-pasts"</string>
-    <string name="dial" msgid="4204975095406423102">"Tālrunis"</string>
-    <string name="map" msgid="6068210738233985748">"Kartes"</string>
-    <string name="browse" msgid="6993590095938149861">"Pārlūkprogramma"</string>
-    <string name="sms" msgid="8250353543787396737">"Īsziņas"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontaktpersona"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Paliek maz brīvas vietas"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Dažas sistēmas funkcijas var nedarboties."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sistēmai pietrūkst vietas. Atbrīvojiet vismaz 250 MB vietas un restartējiet ierīci."</string>
@@ -1825,4 +1830,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM karti nav atļauts izmantot"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Tālruni nav atļauts izmantot"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Uznirstošais logs"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"Vēl <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-af/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-af/strings.xml
index fc20be6..e251b61 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-af/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Foon nie toegelaat nie MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-am/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-am/strings.xml
index fc20be6..c5cc421 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-am/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"ስልክ አይፈቀድም MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-ar/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-ar/strings.xml
index fc20be6..ae68ed4 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-ar/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"‏غير مسموح باستخدام الهاتف MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-az/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-az/strings.xml
index fc20be6..7ac0613 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-az/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"MM#6 telefonu dəstəklənmir"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml
index fc20be6..858fdcb 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefon nije dozvoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-be/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-be/strings.xml
index fc20be6..a22b9c4 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-be/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Тэлефон не дапускаецца MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-bg/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-bg/strings.xml
index fc20be6..b311679 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-bg/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Телефонът не е разрешен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-bs/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-bs/strings.xml
index fc20be6..858fdcb 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-bs/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefon nije dozvoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-ca/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-ca/strings.xml
index fc20be6..cfdaf3e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-ca/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telèfon no compatible MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-cs/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-cs/strings.xml
index fc20be6..4a7f221 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-cs/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefon není povolen (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-da/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-da/strings.xml
index fc20be6..6a7a5c8 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-da/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefonen har ikke adgangstilladelse MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-de/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-de/strings.xml
index fc20be6..25b6bd1 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-de/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Smartphone nicht zulässig MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-el/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-el/strings.xml
index fc20be6..ae6b17a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-el/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-en-rAU/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-en-rAU/strings.xml
index fc20be6..231b858 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-en-rAU/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-en-rCA/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-en-rCA/strings.xml
index fc20be6..231b858 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-en-rCA/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-en-rGB/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-en-rGB/strings.xml
index fc20be6..231b858 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-en-rGB/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-en-rIN/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-en-rIN/strings.xml
index fc20be6..231b858 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-en-rIN/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-en-rXC/strings.xml b/core/res/res/values-mcc001-mnc01-en-rXC/strings.xml
new file mode 100644
index 0000000..00e7813
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-en-rXC/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-es-rUS/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-es-rUS/strings.xml
index fc20be6..059c64a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-es-rUS/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-es/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-es/strings.xml
index fc20be6..059c64a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-es/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-et/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-et/strings.xml
index fc20be6..62ff8ec 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-et/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefon pole lubatud MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-eu/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-eu/strings.xml
index fc20be6..2140993 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-eu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefonoa ez da onartzen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc001-mnc01-fa/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc001-mnc01-fa/strings.xml
index e998b9a..3d1acdb 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-fa/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc001-mnc01-fi/strings.xml
similarity index 66%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc001-mnc01-fi/strings.xml
index e998b9a..1c75bb6 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-fi/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-fr-rCA/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-fr-rCA/strings.xml
index fc20be6..dbb6052 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-fr-rCA/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-fr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-fr/strings.xml
index fc20be6..dbb6052 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-fr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-gl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-gl/strings.xml
index fc20be6..a9cd85e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-gl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Non se admite o teléfono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-hr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-hr/strings.xml
index fc20be6..a3b89c9 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-hr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefon nije dopušten MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc001-mnc01-hu/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc001-mnc01-hu/strings.xml
index e998b9a..e591979 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-hu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-hy/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-hy/strings.xml
index fc20be6..90a840c 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-hy/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-in/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-in/strings.xml
index fc20be6..1496178 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-in/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Ponsel tidak diizinkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-is/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-is/strings.xml
index fc20be6..cb33a8c 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-is/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Sími ekki leyfður MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-it/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-it/strings.xml
index fc20be6..ce902c7 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-it/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefono non consentito MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-ja/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-ja/strings.xml
index fc20be6..6661e5f 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-ja/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"電話は許可されていません(MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-ka/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-ka/strings.xml
index fc20be6..3d8e1b2 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-ka/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"ტელეფონი დაუშვებელია MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-kk/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-kk/strings.xml
index fc20be6..ba210c2 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-kk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Телефон пайдалануға болмайды MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-km/strings.xml
similarity index 61%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-km/strings.xml
index fc20be6..2ee5b75 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-km/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc001-mnc01-ko/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc001-mnc01-ko/strings.xml
index e998b9a..39b839b 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-ko/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-ky/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-ky/strings.xml
index fc20be6..28a2fd0 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-ky/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Телефонду колдонууга тыюу салынган MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-lo/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-lo/strings.xml
index fc20be6..ca560ce4 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-lo/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-lt/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-lt/strings.xml
index fc20be6..29f1433 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-lt/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefonas neleidžiamas (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-lv/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-lv/strings.xml
index fc20be6..0e97385 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-lv/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Tālruni nav atļauts izmantot: MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-mk/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-mk/strings.xml
index fc20be6..f488183 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-mk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Телефонот не е дозволен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-mn/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-mn/strings.xml
index fc20be6..164462b 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-mn/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Утсыг зөвшөөрөөгүй MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-ms/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-ms/strings.xml
index fc20be6..1399187 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-ms/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefon tidak dibenarkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-my/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-my/strings.xml
index fc20be6..39fa0e3 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-my/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-nb/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-nb/strings.xml
index fc20be6..0d46cee 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-nb/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefonen er ikke tillatt, MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-nl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-nl/strings.xml
index fc20be6..adf5d3a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-nl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefoon niet toegestaan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-pl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-pl/strings.xml
index fc20be6..1ee5497 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-pl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"MM#6 – telefon niedozwolony"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-pt-rBR/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-pt-rBR/strings.xml
index fc20be6..4eeb835 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-pt-rBR/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-pt-rPT/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-pt-rPT/strings.xml
index fc20be6..9de5a17 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-pt-rPT/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telemóvel não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-pt/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-pt/strings.xml
index fc20be6..4eeb835 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-pt/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-ro/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-ro/strings.xml
index fc20be6..67f05da 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-ro/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefonul nu este permis MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-ru/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-ru/strings.xml
index fc20be6..59a0f40 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-ru/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Звонки запрещены (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-si/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-si/strings.xml
index fc20be6..bf48fd0 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-si/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-sk/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-sk/strings.xml
index fc20be6..8c23a50 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-sk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefón nie je povolený (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-sl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-sl/strings.xml
index fc20be6..ef0e4f7 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-sl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefon ni dovoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-sq/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-sq/strings.xml
index fc20be6..57cd6ab 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-sq/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefoni nuk lejohet MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-sr/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-sr/strings.xml
index fc20be6..a7ef974ac 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-sr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Телефон није дозвољен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-sv/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-sv/strings.xml
index fc20be6..dc903f6 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-sv/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Mobil tillåts inte MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-sw/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-sw/strings.xml
index fc20be6..c09faee 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-sw/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Simu hairuhusiwi MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-te/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-te/strings.xml
index fc20be6..9e0a1fc 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-te/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-th/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-th/strings.xml
index fc20be6..f16f43f 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-th/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-tl/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-tl/strings.xml
index fc20be6..aa15f0e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-tl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Hindi pinapahintulutan ang telepono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-tr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-tr/strings.xml
index fc20be6..7d0c4c2 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-tr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Telefona izin verilmiyor MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-uk/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-uk/strings.xml
index fc20be6..d791af4 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-uk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Телефон заборонено (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-uz/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-uz/strings.xml
index fc20be6..73ac1c0 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-uz/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Chaqiruvlar taqiqlangan (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-vi/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-vi/strings.xml
index fc20be6..e9362de 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-vi/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Không cho phép điện thoại MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-zh-rCN/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-zh-rCN/strings.xml
index fc20be6..c9abc9b 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-zh-rCN/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"不受允许的手机 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc001-mnc01-zh-rHK/strings.xml
similarity index 66%
rename from core/res/res/values-large/strings.xml
rename to core/res/res/values-mcc001-mnc01-zh-rHK/strings.xml
index e998b9a..375fe31 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-zh-rHK/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-zh-rTW/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-zh-rTW/strings.xml
index fc20be6..5700f01 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-zh-rTW/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"不支援的手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01-zu/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc001-mnc01-zu/strings.xml
index fc20be6..b31303f 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-zu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="2238090225563073546">"Ifoni ayivunyelwe MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc001-mnc01/strings.xml
similarity index 78%
rename from core/res/res/values-xlarge/strings.xml
rename to core/res/res/values-mcc001-mnc01/strings.xml
index fc20be6..96af975 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc001-mnc01/strings.xml
@@ -2,7 +2,7 @@
 <!--
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -18,8 +18,5 @@
 */
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc030-af/strings.xml b/core/res/res/values-mcc310-mnc030-af/strings.xml
index 0b666c2..1b6eec8 100644
--- a/core/res/res/values-mcc310-mnc030-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-am/strings.xml b/core/res/res/values-mcc310-mnc030-am/strings.xml
index 08c5e32..9e10ee2 100644
--- a/core/res/res/values-mcc310-mnc030-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ar/strings.xml b/core/res/res/values-mcc310-mnc030-ar/strings.xml
index 5d6a53d..51db337 100644
--- a/core/res/res/values-mcc310-mnc030-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-az/strings.xml b/core/res/res/values-mcc310-mnc030-az/strings.xml
index 194d189..3946a0f 100644
--- a/core/res/res/values-mcc310-mnc030-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml
index d306893..6dfa886 100644
--- a/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM kartica nije podešena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-be/strings.xml b/core/res/res/values-mcc310-mnc030-be/strings.xml
index 12fef7a..66992cb 100644
--- a/core/res/res/values-mcc310-mnc030-be/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-be/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-карты няма MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-карта не дапускаецца MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Тэлефон не дапускаецца MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-bg/strings.xml b/core/res/res/values-mcc310-mnc030-bg/strings.xml
index a7c014a..336a890 100644
--- a/core/res/res/values-mcc310-mnc030-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-bn/strings.xml b/core/res/res/values-mcc310-mnc030-bn/strings.xml
index f07a3d6..d6c887a 100644
--- a/core/res/res/values-mcc310-mnc030-bn/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-bn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"সিমের অনুমতি নেই MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-bs/strings.xml b/core/res/res/values-mcc310-mnc030-bs/strings.xml
index 1e6c7db..c17d685 100644
--- a/core/res/res/values-mcc310-mnc030-bs/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-bs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM kartica nije dodijeljena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ca/strings.xml b/core/res/res/values-mcc310-mnc030-ca/strings.xml
index af25f9b..1e4a752 100644
--- a/core/res/res/values-mcc310-mnc030-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-cs/strings.xml b/core/res/res/values-mcc310-mnc030-cs/strings.xml
index ee0f90c..e5c0cf2 100644
--- a/core/res/res/values-mcc310-mnc030-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-da/strings.xml b/core/res/res/values-mcc310-mnc030-da/strings.xml
index 8539f7a..dab4912 100644
--- a/core/res/res/values-mcc310-mnc030-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-de/strings.xml b/core/res/res/values-mcc310-mnc030-de/strings.xml
index ad797b5..d3ff1164 100644
--- a/core/res/res/values-mcc310-mnc030-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-el/strings.xml b/core/res/res/values-mcc310-mnc030-el/strings.xml
index 62aa97f..22afb5f 100644
--- a/core/res/res/values-mcc310-mnc030-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml
index 1a50ac6..c604346 100644
--- a/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rCA/strings.xml b/core/res/res/values-mcc310-mnc030-en-rCA/strings.xml
index 1a50ac6..c604346 100644
--- a/core/res/res/values-mcc310-mnc030-en-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-en-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml
index 1a50ac6..c604346 100644
--- a/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml
index 1a50ac6..c604346 100644
--- a/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rXC/strings.xml b/core/res/res/values-mcc310-mnc030-en-rXC/strings.xml
index 5eb9cba..6fbbcb7 100644
--- a/core/res/res/values-mcc310-mnc030-en-rXC/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-en-rXC/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎SIM not provisioned MM#2‎‏‎‎‏‎"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‎SIM not allowed MM#3‎‏‎‎‏‎"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‏‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml
index 87226ac..42426cb 100644
--- a/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-es/strings.xml b/core/res/res/values-mcc310-mnc030-es/strings.xml
index c13f5f8..ea3224d 100644
--- a/core/res/res/values-mcc310-mnc030-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-et/strings.xml b/core/res/res/values-mcc310-mnc030-et/strings.xml
index 07229ab..fbcaa30 100644
--- a/core/res/res/values-mcc310-mnc030-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-eu/strings.xml b/core/res/res/values-mcc310-mnc030-eu/strings.xml
index 024fbab..4053e48 100644
--- a/core/res/res/values-mcc310-mnc030-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-fa/strings.xml b/core/res/res/values-mcc310-mnc030-fa/strings.xml
index e754032..01b0ad3 100644
--- a/core/res/res/values-mcc310-mnc030-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-fi/strings.xml b/core/res/res/values-mcc310-mnc030-fi/strings.xml
index 3b9c2ab..8e948c6 100644
--- a/core/res/res/values-mcc310-mnc030-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml
index 31644b7..0e4f55d 100644
--- a/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-fr/strings.xml b/core/res/res/values-mcc310-mnc030-fr/strings.xml
index 9c690e7..2f001db 100644
--- a/core/res/res/values-mcc310-mnc030-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-gl/strings.xml b/core/res/res/values-mcc310-mnc030-gl/strings.xml
index 59be216..fe18f6e 100644
--- a/core/res/res/values-mcc310-mnc030-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-gu/strings.xml b/core/res/res/values-mcc310-mnc030-gu/strings.xml
index ac57a85..626e8b6 100644
--- a/core/res/res/values-mcc310-mnc030-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-gu/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-hi/strings.xml b/core/res/res/values-mcc310-mnc030-hi/strings.xml
index 244d175..4ecf10a 100644
--- a/core/res/res/values-mcc310-mnc030-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-hi/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM की अनुमति नहीं है MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-hr/strings.xml b/core/res/res/values-mcc310-mnc030-hr/strings.xml
index a37043c..a938a55 100644
--- a/core/res/res/values-mcc310-mnc030-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-hu/strings.xml b/core/res/res/values-mcc310-mnc030-hu/strings.xml
index b26b2b2..b28ce8e 100644
--- a/core/res/res/values-mcc310-mnc030-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-hy/strings.xml b/core/res/res/values-mcc310-mnc030-hy/strings.xml
index 0d052f3..34cd04e 100644
--- a/core/res/res/values-mcc310-mnc030-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-in/strings.xml b/core/res/res/values-mcc310-mnc030-in/strings.xml
index f8f6613..b2a94b9 100644
--- a/core/res/res/values-mcc310-mnc030-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-is/strings.xml b/core/res/res/values-mcc310-mnc030-is/strings.xml
index 1033965..008de9d 100644
--- a/core/res/res/values-mcc310-mnc030-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-it/strings.xml b/core/res/res/values-mcc310-mnc030-it/strings.xml
index fb74a97..1b17cff 100644
--- a/core/res/res/values-mcc310-mnc030-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-iw/strings.xml b/core/res/res/values-mcc310-mnc030-iw/strings.xml
index 50bd517..7d26d77 100644
--- a/core/res/res/values-mcc310-mnc030-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-iw/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ja/strings.xml b/core/res/res/values-mcc310-mnc030-ja/strings.xml
index 78cd78c..56fa5dd 100644
--- a/core/res/res/values-mcc310-mnc030-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ka/strings.xml b/core/res/res/values-mcc310-mnc030-ka/strings.xml
index 04d6a7d..abcaa99 100644
--- a/core/res/res/values-mcc310-mnc030-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-kk/strings.xml b/core/res/res/values-mcc310-mnc030-kk/strings.xml
index aad588c..b84e25f 100644
--- a/core/res/res/values-mcc310-mnc030-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-km/strings.xml b/core/res/res/values-mcc310-mnc030-km/strings.xml
index bd99927..284310a 100644
--- a/core/res/res/values-mcc310-mnc030-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ស៊ីមកាត​មិនត្រូវបាន​ផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាត​ទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-kn/strings.xml b/core/res/res/values-mcc310-mnc030-kn/strings.xml
index 39e9b070..a1335ed 100644
--- a/core/res/res/values-mcc310-mnc030-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-kn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ko/strings.xml b/core/res/res/values-mcc310-mnc030-ko/strings.xml
index 67e45b0..f9b2e5c 100644
--- a/core/res/res/values-mcc310-mnc030-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ky/strings.xml b/core/res/res/values-mcc310-mnc030-ky/strings.xml
index 02ac153..a0c42fe 100644
--- a/core/res/res/values-mcc310-mnc030-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ky/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM карта таанылган жок (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-lo/strings.xml b/core/res/res/values-mcc310-mnc030-lo/strings.xml
index b41bf91..f8f57c4 100644
--- a/core/res/res/values-mcc310-mnc030-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-lt/strings.xml b/core/res/res/values-mcc310-mnc030-lt/strings.xml
index 59c66be..2060253 100644
--- a/core/res/res/values-mcc310-mnc030-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-lv/strings.xml b/core/res/res/values-mcc310-mnc030-lv/strings.xml
index 685c9b8..dd8e155 100644
--- a/core/res/res/values-mcc310-mnc030-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-mk/strings.xml b/core/res/res/values-mcc310-mnc030-mk/strings.xml
index ce24e25..3fa9acb 100644
--- a/core/res/res/values-mcc310-mnc030-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ml/strings.xml b/core/res/res/values-mcc310-mnc030-ml/strings.xml
index 9adfd9c..b382040 100644
--- a/core/res/res/values-mcc310-mnc030-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ml/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-mn/strings.xml b/core/res/res/values-mcc310-mnc030-mn/strings.xml
index 6ff2d5e..5bbbe1a 100644
--- a/core/res/res/values-mcc310-mnc030-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-mr/strings.xml b/core/res/res/values-mcc310-mnc030-mr/strings.xml
index afc40a1..ffead44 100644
--- a/core/res/res/values-mcc310-mnc030-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-mr/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ms/strings.xml b/core/res/res/values-mcc310-mnc030-ms/strings.xml
index 9a54b04..2bcfc77 100644
--- a/core/res/res/values-mcc310-mnc030-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-my/strings.xml b/core/res/res/values-mcc310-mnc030-my/strings.xml
index 79a0791..7e8894e 100644
--- a/core/res/res/values-mcc310-mnc030-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-nb/strings.xml b/core/res/res/values-mcc310-mnc030-nb/strings.xml
index 7c06dba..267353e 100644
--- a/core/res/res/values-mcc310-mnc030-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ne/strings.xml b/core/res/res/values-mcc310-mnc030-ne/strings.xml
index 3ef06ab..923e9aa 100644
--- a/core/res/res/values-mcc310-mnc030-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ne/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM लाई अनुमति छैन MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-nl/strings.xml b/core/res/res/values-mcc310-mnc030-nl/strings.xml
index 861385d..52b52d6 100644
--- a/core/res/res/values-mcc310-mnc030-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-pa/strings.xml b/core/res/res/values-mcc310-mnc030-pa/strings.xml
index ba7b614..42a62b3 100644
--- a/core/res/res/values-mcc310-mnc030-pa/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-pa/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-pl/strings.xml b/core/res/res/values-mcc310-mnc030-pl/strings.xml
index 84ff351..fa5720a 100644
--- a/core/res/res/values-mcc310-mnc030-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml
index 2679f93..663261c 100644
--- a/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml
index 2679f93..602b59e 100644
--- a/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-pt/strings.xml b/core/res/res/values-mcc310-mnc030-pt/strings.xml
index 2679f93..663261c 100644
--- a/core/res/res/values-mcc310-mnc030-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ro/strings.xml b/core/res/res/values-mcc310-mnc030-ro/strings.xml
index 5bae0c0..77d374c 100644
--- a/core/res/res/values-mcc310-mnc030-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ru/strings.xml b/core/res/res/values-mcc310-mnc030-ru/strings.xml
index 658badf..c2ca9d3 100644
--- a/core/res/res/values-mcc310-mnc030-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-si/strings.xml b/core/res/res/values-mcc310-mnc030-si/strings.xml
index 635ffa4..9b9b1b7 100644
--- a/core/res/res/values-mcc310-mnc030-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sk/strings.xml b/core/res/res/values-mcc310-mnc030-sk/strings.xml
index 2a046b6..968fd2d 100644
--- a/core/res/res/values-mcc310-mnc030-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sl/strings.xml b/core/res/res/values-mcc310-mnc030-sl/strings.xml
index 7321e4d..dcbf3e2 100644
--- a/core/res/res/values-mcc310-mnc030-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sq/strings.xml b/core/res/res/values-mcc310-mnc030-sq/strings.xml
index e553f01..4ea64fd 100644
--- a/core/res/res/values-mcc310-mnc030-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sr/strings.xml b/core/res/res/values-mcc310-mnc030-sr/strings.xml
index 945e2fc..2f36c77 100644
--- a/core/res/res/values-mcc310-mnc030-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sv/strings.xml b/core/res/res/values-mcc310-mnc030-sv/strings.xml
index 5f0cc46..bac0d61 100644
--- a/core/res/res/values-mcc310-mnc030-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sw/strings.xml b/core/res/res/values-mcc310-mnc030-sw/strings.xml
index fbd2076..c26e864 100644
--- a/core/res/res/values-mcc310-mnc030-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ta/strings.xml b/core/res/res/values-mcc310-mnc030-ta/strings.xml
index 6fc3df6..51b1026 100644
--- a/core/res/res/values-mcc310-mnc030-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ta/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-te/strings.xml b/core/res/res/values-mcc310-mnc030-te/strings.xml
index 4c61791..12a0d70 100644
--- a/core/res/res/values-mcc310-mnc030-te/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-te/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM MM#2ని సక్రియం చేయలేదు"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ఫోన్ అనుమతించబడదు MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-th/strings.xml b/core/res/res/values-mcc310-mnc030-th/strings.xml
index 9a8ee74..d4b2dc4 100644
--- a/core/res/res/values-mcc310-mnc030-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-tl/strings.xml b/core/res/res/values-mcc310-mnc030-tl/strings.xml
index 6408f4e..41d3924 100644
--- a/core/res/res/values-mcc310-mnc030-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-tr/strings.xml b/core/res/res/values-mcc310-mnc030-tr/strings.xml
index 361ee9c..aab27e2 100644
--- a/core/res/res/values-mcc310-mnc030-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-uk/strings.xml b/core/res/res/values-mcc310-mnc030-uk/strings.xml
index efee94e..9e0cd4c 100644
--- a/core/res/res/values-mcc310-mnc030-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ur/strings.xml b/core/res/res/values-mcc310-mnc030-ur/strings.xml
index a0e5fd6..d919735 100644
--- a/core/res/res/values-mcc310-mnc030-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ur/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (2995576894416087107) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-uz/strings.xml b/core/res/res/values-mcc310-mnc030-uz/strings.xml
index 7eb641a..c7ae871 100644
--- a/core/res/res/values-mcc310-mnc030-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-vi/strings.xml b/core/res/res/values-mcc310-mnc030-vi/strings.xml
index 362ee6a..bd87e0d 100644
--- a/core/res/res/values-mcc310-mnc030-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml
index efa43f5..441eb3f 100644
--- a/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml
index c163544..7f3a94c4 100644
--- a/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml
index c163544..a4baf62 100644
--- a/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-zu/strings.xml b/core/res/res/values-mcc310-mnc030-zu/strings.xml
index 720fa82..0142a35 100644
--- a/core/res/res/values-mcc310-mnc030-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030/strings.xml b/core/res/res/values-mcc310-mnc030/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc030/strings.xml
+++ b/core/res/res/values-mcc310-mnc030/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-af/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-af/strings.xml
index fc20be6..bfc24ab 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-af/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Foon nie toegelaat nie MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-am/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-am/strings.xml
index fc20be6..c75ae67 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-am/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"ስልክ አይፈቀድም MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-ar/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-ar/strings.xml
index fc20be6..a3a5d85 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-ar/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"‏غير مسموح باستخدام الهاتف MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-az/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-az/strings.xml
index fc20be6..4c7a339 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-az/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"MM#6 telefonu dəstəklənmir"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml
index fc20be6..d40e0bf 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefon nije dozvoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-be/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-be/strings.xml
index fc20be6..31caa9a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-be/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Тэлефон не дапускаецца MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-bg/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-bg/strings.xml
index fc20be6..70445e1 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-bg/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Телефонът не е разрешен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-bs/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-bs/strings.xml
index fc20be6..be60b92 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-bs/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefon nije dozvoljen  MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-ca/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-ca/strings.xml
index fc20be6..836aab0 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-ca/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telèfon no compatible MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-cs/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-cs/strings.xml
index fc20be6..f31b34e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-cs/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefon není povolen (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-da/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-da/strings.xml
index fc20be6..1213be0 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-da/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefonen har ikke adgangstilladelse MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-de/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-de/strings.xml
index fc20be6..7fdf306 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-de/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Smartphone nicht zulässig MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-el/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-el/strings.xml
index fc20be6..9dfeb6c 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-el/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-en-rAU/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-en-rAU/strings.xml
index fc20be6..afeb95e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-en-rAU/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-en-rCA/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-en-rCA/strings.xml
index fc20be6..afeb95e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-en-rCA/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-en-rGB/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-en-rGB/strings.xml
index fc20be6..afeb95e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-en-rGB/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-en-rIN/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-en-rIN/strings.xml
index fc20be6..afeb95e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-en-rIN/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-en-rXC/strings.xml b/core/res/res/values-mcc310-mnc150-en-rXC/strings.xml
new file mode 100644
index 0000000..c3d43d9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-en-rXC/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‎‏‏‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-es-rUS/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-es-rUS/strings.xml
index fc20be6..4ed5253 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-es-rUS/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-es/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-es/strings.xml
index fc20be6..4ed5253 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-es/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-et/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-et/strings.xml
index fc20be6..6cb111e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-et/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefon pole lubatud MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-eu/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-eu/strings.xml
index fc20be6..a38ed44d 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-eu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefonoa ez da onartzen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc310-mnc150-fa/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc310-mnc150-fa/strings.xml
index e998b9a..bb52d79 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-fa/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc310-mnc150-fi/strings.xml
similarity index 66%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc310-mnc150-fi/strings.xml
index e998b9a..d1eff31 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-fi/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-fr-rCA/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-fr-rCA/strings.xml
index fc20be6..335a0e8 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-fr-rCA/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-fr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-fr/strings.xml
index fc20be6..335a0e8 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-fr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-gl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-gl/strings.xml
index fc20be6..23faa06 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-gl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Non se admite o teléfono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-hr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-hr/strings.xml
index fc20be6..85bc29b 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-hr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefon nije dopušten MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc310-mnc150-hu/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc310-mnc150-hu/strings.xml
index e998b9a..e741ab3 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-hu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-hy/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-hy/strings.xml
index fc20be6..c6ec7d3 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-hy/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-in/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-in/strings.xml
index fc20be6..8a4fb2a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-in/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Ponsel tidak diizinkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-is/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-is/strings.xml
index fc20be6..3c1a883 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-is/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Sími ekki leyfður MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-it/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-it/strings.xml
index fc20be6..1fed454 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-it/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefono non consentito MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-ja/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-ja/strings.xml
index fc20be6..9b4a071 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-ja/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"電話は許可されていません(MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-ka/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-ka/strings.xml
index fc20be6..5387ec5 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-ka/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"ტელეფონი დაუშვებელია MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-kk/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-kk/strings.xml
index fc20be6..b8b20fd 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-kk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Телефон пайдалануға болмайды MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-km/strings.xml
similarity index 61%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-km/strings.xml
index fc20be6..032f361 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-km/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc310-mnc150-ko/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc310-mnc150-ko/strings.xml
index e998b9a..94314c4 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-ko/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-ky/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-ky/strings.xml
index fc20be6..238bef7 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-ky/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Телефонду колдонууга тыюу салынган MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-lo/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-lo/strings.xml
index fc20be6..fb7fcc2 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-lo/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-lt/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-lt/strings.xml
index fc20be6..59fa06a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-lt/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefonas neleidžiamas (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-lv/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-lv/strings.xml
index fc20be6..c1021d7 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-lv/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Tālruni nav atļauts izmantot: MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-mk/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-mk/strings.xml
index fc20be6..934e03c 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-mk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Телефонот не е дозволен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-mn/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-mn/strings.xml
index fc20be6..4a56ecf 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-mn/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Утсыг зөвшөөрөөгүй MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-ms/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-ms/strings.xml
index fc20be6..7fe8b74 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-ms/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefon tidak dibenarkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-my/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-my/strings.xml
index fc20be6..c1b0918 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-my/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-nb/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-nb/strings.xml
index fc20be6..a792c97 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-nb/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefonen er ikke tillatt, MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-nl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-nl/strings.xml
index fc20be6..219c0c3 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-nl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefoon niet toegestaan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-pl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-pl/strings.xml
index fc20be6..a696993 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-pl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"MM#6 – telefon niedozwolony"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-pt-rBR/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-pt-rBR/strings.xml
index fc20be6..1163c91 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-pt-rBR/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-pt-rPT/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-pt-rPT/strings.xml
index fc20be6..13bcac8 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-pt-rPT/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telemóvel não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-pt/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-pt/strings.xml
index fc20be6..1163c91 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-pt/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-ro/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-ro/strings.xml
index fc20be6..200b59d 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-ro/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefonul nu este permis MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-ru/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-ru/strings.xml
index fc20be6..7118395 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-ru/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Звонки запрещены (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-si/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-si/strings.xml
index fc20be6..c198a38 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-si/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-sk/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-sk/strings.xml
index fc20be6..0a0d119 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-sk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefón nie je povolený (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-sl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-sl/strings.xml
index fc20be6..cebc04a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-sl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefon ni dovoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-sq/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-sq/strings.xml
index fc20be6..2daf805 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-sq/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefoni nuk lejohet MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-sr/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-sr/strings.xml
index fc20be6..40ac0c2 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-sr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Телефон није дозвољен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-sv/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-sv/strings.xml
index fc20be6..5f1a340 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-sv/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Mobil tillåts inte MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-sw/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-sw/strings.xml
index fc20be6..db3201d 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-sw/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Simu hairuhusiwi MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-te/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-te/strings.xml
index fc20be6..e8bb029 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-te/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-th/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-th/strings.xml
index fc20be6..e047ebe 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-th/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-tl/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-tl/strings.xml
index fc20be6..550acde 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-tl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Hindi pinapahintulutan ang telepono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-tr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-tr/strings.xml
index fc20be6..60615bb 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-tr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Telefona izin verilmiyor MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-uk/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-uk/strings.xml
index fc20be6..b709f6e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-uk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Телефон заборонено (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-uz/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-uz/strings.xml
index fc20be6..e1372d1 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-uz/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Chaqiruvlar taqiqlangan (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-vi/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-vi/strings.xml
index fc20be6..85a7c62 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-vi/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Không cho phép điện thoại MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-zh-rCN/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-zh-rCN/strings.xml
index fc20be6..9319941 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-zh-rCN/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"不受允许的手机 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc310-mnc150-zh-rHK/strings.xml
similarity index 66%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc310-mnc150-zh-rHK/strings.xml
index e998b9a..092d780 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-zh-rHK/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-zh-rTW/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-zh-rTW/strings.xml
index fc20be6..f8d43ed 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-zh-rTW/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"不支援的手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150-zu/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150-zu/strings.xml
index fc20be6..4d0f31d 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-zu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="5207603948149789531">"Ifoni ayivunyelwe MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc310-mnc150/strings.xml
similarity index 78%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc310-mnc150/strings.xml
index fc20be6..96af975 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc310-mnc150/strings.xml
@@ -2,7 +2,7 @@
 <!--
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -18,8 +18,5 @@
 */
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc170-af/strings.xml b/core/res/res/values-mcc310-mnc170-af/strings.xml
index 4256d3a..00c2835 100644
--- a/core/res/res/values-mcc310-mnc170-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-am/strings.xml b/core/res/res/values-mcc310-mnc170-am/strings.xml
index 311d9e1..961fa69 100644
--- a/core/res/res/values-mcc310-mnc170-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ar/strings.xml b/core/res/res/values-mcc310-mnc170-ar/strings.xml
index a80ff2e..3ad58f5 100644
--- a/core/res/res/values-mcc310-mnc170-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-az/strings.xml b/core/res/res/values-mcc310-mnc170-az/strings.xml
index a690668..43491fa 100644
--- a/core/res/res/values-mcc310-mnc170-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml
index b2da8a7..f47ef72 100644
--- a/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM kartica nije podešena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-be/strings.xml b/core/res/res/values-mcc310-mnc170-be/strings.xml
index fb7f556..f596195 100644
--- a/core/res/res/values-mcc310-mnc170-be/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-be/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-карты няма MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-карта не дапускаецца MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Тэлефон не дапускаецца MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-bg/strings.xml b/core/res/res/values-mcc310-mnc170-bg/strings.xml
index 1158b3b..b93c5c1 100644
--- a/core/res/res/values-mcc310-mnc170-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-bn/strings.xml b/core/res/res/values-mcc310-mnc170-bn/strings.xml
index 4e6d41b..5102b45 100644
--- a/core/res/res/values-mcc310-mnc170-bn/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-bn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"সিমের অনুমতি নেই MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-bs/strings.xml b/core/res/res/values-mcc310-mnc170-bs/strings.xml
index d3f3e3b..4a2cb6f 100644
--- a/core/res/res/values-mcc310-mnc170-bs/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-bs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM kartica nije dodijeljena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ca/strings.xml b/core/res/res/values-mcc310-mnc170-ca/strings.xml
index 9abeeb7..c82d5a5 100644
--- a/core/res/res/values-mcc310-mnc170-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-cs/strings.xml b/core/res/res/values-mcc310-mnc170-cs/strings.xml
index 2d4d2fb..2443292 100644
--- a/core/res/res/values-mcc310-mnc170-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-da/strings.xml b/core/res/res/values-mcc310-mnc170-da/strings.xml
index ae2155f..98ab336 100644
--- a/core/res/res/values-mcc310-mnc170-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-de/strings.xml b/core/res/res/values-mcc310-mnc170-de/strings.xml
index f7c5eec..f3c0b9a 100644
--- a/core/res/res/values-mcc310-mnc170-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-el/strings.xml b/core/res/res/values-mcc310-mnc170-el/strings.xml
index 68b7008..42000eb 100644
--- a/core/res/res/values-mcc310-mnc170-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml
index fd16620..d389436 100644
--- a/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rCA/strings.xml b/core/res/res/values-mcc310-mnc170-en-rCA/strings.xml
index fd16620..d389436 100644
--- a/core/res/res/values-mcc310-mnc170-en-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-en-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml
index fd16620..d389436 100644
--- a/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml
index fd16620..d389436 100644
--- a/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rXC/strings.xml b/core/res/res/values-mcc310-mnc170-en-rXC/strings.xml
index 71d087e..054db20 100644
--- a/core/res/res/values-mcc310-mnc170-en-rXC/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-en-rXC/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎SIM not provisioned MM#2‎‏‎‎‏‎"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‎‏‎‎SIM not allowed MM#3‎‏‎‎‏‎"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‎‎‎‏‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml
index 50d3c12..c794ad8 100644
--- a/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-es/strings.xml b/core/res/res/values-mcc310-mnc170-es/strings.xml
index 7191d04..5e0852a 100644
--- a/core/res/res/values-mcc310-mnc170-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-et/strings.xml b/core/res/res/values-mcc310-mnc170-et/strings.xml
index 7159bf9..24a004f 100644
--- a/core/res/res/values-mcc310-mnc170-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-eu/strings.xml b/core/res/res/values-mcc310-mnc170-eu/strings.xml
index 797f988..4f7b0d1 100644
--- a/core/res/res/values-mcc310-mnc170-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-fa/strings.xml b/core/res/res/values-mcc310-mnc170-fa/strings.xml
index 968f952..1a516c4 100644
--- a/core/res/res/values-mcc310-mnc170-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-fi/strings.xml b/core/res/res/values-mcc310-mnc170-fi/strings.xml
index c0523f4..e638085 100644
--- a/core/res/res/values-mcc310-mnc170-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml
index 5600fa4..3b87213 100644
--- a/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-fr/strings.xml b/core/res/res/values-mcc310-mnc170-fr/strings.xml
index 73b4f0e..0f6adf0 100644
--- a/core/res/res/values-mcc310-mnc170-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-gl/strings.xml b/core/res/res/values-mcc310-mnc170-gl/strings.xml
index fe13211..a2513d2 100644
--- a/core/res/res/values-mcc310-mnc170-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-gu/strings.xml b/core/res/res/values-mcc310-mnc170-gu/strings.xml
index 60eba5b..0bfec25 100644
--- a/core/res/res/values-mcc310-mnc170-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-gu/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-hi/strings.xml b/core/res/res/values-mcc310-mnc170-hi/strings.xml
index eb350b0..e20f6da 100644
--- a/core/res/res/values-mcc310-mnc170-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-hi/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM की अनुमति नहीं है MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-hr/strings.xml b/core/res/res/values-mcc310-mnc170-hr/strings.xml
index d5cf025..e640ae5 100644
--- a/core/res/res/values-mcc310-mnc170-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-hu/strings.xml b/core/res/res/values-mcc310-mnc170-hu/strings.xml
index e05e700..8d6dd9f 100644
--- a/core/res/res/values-mcc310-mnc170-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-hy/strings.xml b/core/res/res/values-mcc310-mnc170-hy/strings.xml
index 90a5f6d..3c30292 100644
--- a/core/res/res/values-mcc310-mnc170-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-in/strings.xml b/core/res/res/values-mcc310-mnc170-in/strings.xml
index fc1bd0a..51a82df 100644
--- a/core/res/res/values-mcc310-mnc170-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-is/strings.xml b/core/res/res/values-mcc310-mnc170-is/strings.xml
index eef786c..e9c6d48 100644
--- a/core/res/res/values-mcc310-mnc170-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-it/strings.xml b/core/res/res/values-mcc310-mnc170-it/strings.xml
index eaf0abc..8e97b1b 100644
--- a/core/res/res/values-mcc310-mnc170-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-iw/strings.xml b/core/res/res/values-mcc310-mnc170-iw/strings.xml
index edee703..5fc0862 100644
--- a/core/res/res/values-mcc310-mnc170-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-iw/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ja/strings.xml b/core/res/res/values-mcc310-mnc170-ja/strings.xml
index 6942641..b019dd1 100644
--- a/core/res/res/values-mcc310-mnc170-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ka/strings.xml b/core/res/res/values-mcc310-mnc170-ka/strings.xml
index 6f6c4aa..fe5bc11 100644
--- a/core/res/res/values-mcc310-mnc170-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-kk/strings.xml b/core/res/res/values-mcc310-mnc170-kk/strings.xml
index 210fb31..2f24d65 100644
--- a/core/res/res/values-mcc310-mnc170-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-km/strings.xml b/core/res/res/values-mcc310-mnc170-km/strings.xml
index 79acf48..4a121e4 100644
--- a/core/res/res/values-mcc310-mnc170-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-kn/strings.xml b/core/res/res/values-mcc310-mnc170-kn/strings.xml
index e11523b..d59c95c 100644
--- a/core/res/res/values-mcc310-mnc170-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-kn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ko/strings.xml b/core/res/res/values-mcc310-mnc170-ko/strings.xml
index 22d7e35..783e7d5 100644
--- a/core/res/res/values-mcc310-mnc170-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ky/strings.xml b/core/res/res/values-mcc310-mnc170-ky/strings.xml
index 1f07c68..4c09085 100644
--- a/core/res/res/values-mcc310-mnc170-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ky/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM карта таанылган жок (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-lo/strings.xml b/core/res/res/values-mcc310-mnc170-lo/strings.xml
index 3073000..e0a7379 100644
--- a/core/res/res/values-mcc310-mnc170-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-lt/strings.xml b/core/res/res/values-mcc310-mnc170-lt/strings.xml
index 127e69f..25698a9 100644
--- a/core/res/res/values-mcc310-mnc170-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-lv/strings.xml b/core/res/res/values-mcc310-mnc170-lv/strings.xml
index da2ff7c..6bb0838 100644
--- a/core/res/res/values-mcc310-mnc170-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-mk/strings.xml b/core/res/res/values-mcc310-mnc170-mk/strings.xml
index 3bc8194..de6ac62 100644
--- a/core/res/res/values-mcc310-mnc170-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ml/strings.xml b/core/res/res/values-mcc310-mnc170-ml/strings.xml
index 0479aef..b82f374 100644
--- a/core/res/res/values-mcc310-mnc170-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ml/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-mn/strings.xml b/core/res/res/values-mcc310-mnc170-mn/strings.xml
index 59f24ec..6e5cfc3 100644
--- a/core/res/res/values-mcc310-mnc170-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-mr/strings.xml b/core/res/res/values-mcc310-mnc170-mr/strings.xml
index 938207c..776a098 100644
--- a/core/res/res/values-mcc310-mnc170-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-mr/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ms/strings.xml b/core/res/res/values-mcc310-mnc170-ms/strings.xml
index 36be774..698c5d7 100644
--- a/core/res/res/values-mcc310-mnc170-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-my/strings.xml b/core/res/res/values-mcc310-mnc170-my/strings.xml
index 61f1a67..6c2be32 100644
--- a/core/res/res/values-mcc310-mnc170-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-nb/strings.xml b/core/res/res/values-mcc310-mnc170-nb/strings.xml
index 3f213da..3a404b8 100644
--- a/core/res/res/values-mcc310-mnc170-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ne/strings.xml b/core/res/res/values-mcc310-mnc170-ne/strings.xml
index d7febc4..fec148e 100644
--- a/core/res/res/values-mcc310-mnc170-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ne/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM लाई अनुमति छैन MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-nl/strings.xml b/core/res/res/values-mcc310-mnc170-nl/strings.xml
index b1f9ba8..bdfb53a 100644
--- a/core/res/res/values-mcc310-mnc170-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-pa/strings.xml b/core/res/res/values-mcc310-mnc170-pa/strings.xml
index 9e993e3..9d8f861 100644
--- a/core/res/res/values-mcc310-mnc170-pa/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-pa/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-pl/strings.xml b/core/res/res/values-mcc310-mnc170-pl/strings.xml
index d1ecd5d..41100a4 100644
--- a/core/res/res/values-mcc310-mnc170-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml
index fc31e9e..fcffa16 100644
--- a/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml
index fc31e9e..7d43bf3 100644
--- a/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-pt/strings.xml b/core/res/res/values-mcc310-mnc170-pt/strings.xml
index fc31e9e..fcffa16 100644
--- a/core/res/res/values-mcc310-mnc170-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ro/strings.xml b/core/res/res/values-mcc310-mnc170-ro/strings.xml
index 1ee5080..7c2c09e 100644
--- a/core/res/res/values-mcc310-mnc170-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ru/strings.xml b/core/res/res/values-mcc310-mnc170-ru/strings.xml
index 0e00909..3b457da 100644
--- a/core/res/res/values-mcc310-mnc170-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-si/strings.xml b/core/res/res/values-mcc310-mnc170-si/strings.xml
index bbd1e4c..61e0143 100644
--- a/core/res/res/values-mcc310-mnc170-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sk/strings.xml b/core/res/res/values-mcc310-mnc170-sk/strings.xml
index e5f9376..cf71dd3 100644
--- a/core/res/res/values-mcc310-mnc170-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sl/strings.xml b/core/res/res/values-mcc310-mnc170-sl/strings.xml
index 2d4c7dd..2e600ac 100644
--- a/core/res/res/values-mcc310-mnc170-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sq/strings.xml b/core/res/res/values-mcc310-mnc170-sq/strings.xml
index df5b537..0b22ca2 100644
--- a/core/res/res/values-mcc310-mnc170-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sr/strings.xml b/core/res/res/values-mcc310-mnc170-sr/strings.xml
index 6bfbbb2..42057fe 100644
--- a/core/res/res/values-mcc310-mnc170-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sv/strings.xml b/core/res/res/values-mcc310-mnc170-sv/strings.xml
index 1a28db1..c609747 100644
--- a/core/res/res/values-mcc310-mnc170-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sw/strings.xml b/core/res/res/values-mcc310-mnc170-sw/strings.xml
index 0852115..7727944 100644
--- a/core/res/res/values-mcc310-mnc170-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ta/strings.xml b/core/res/res/values-mcc310-mnc170-ta/strings.xml
index 0277cc2..1812ba8 100644
--- a/core/res/res/values-mcc310-mnc170-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ta/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-te/strings.xml b/core/res/res/values-mcc310-mnc170-te/strings.xml
index a208cd3..a088bb0 100644
--- a/core/res/res/values-mcc310-mnc170-te/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-te/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM MM#2ని సక్రియం చేయలేదు"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ఫోన్ అనుమతించబడదు MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-th/strings.xml b/core/res/res/values-mcc310-mnc170-th/strings.xml
index e5d02c8..ad5f5dc 100644
--- a/core/res/res/values-mcc310-mnc170-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-tl/strings.xml b/core/res/res/values-mcc310-mnc170-tl/strings.xml
index e285759..187593a 100644
--- a/core/res/res/values-mcc310-mnc170-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-tr/strings.xml b/core/res/res/values-mcc310-mnc170-tr/strings.xml
index b5102ef..e4a9255 100644
--- a/core/res/res/values-mcc310-mnc170-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-uk/strings.xml b/core/res/res/values-mcc310-mnc170-uk/strings.xml
index 37e3118..89ad9b3 100644
--- a/core/res/res/values-mcc310-mnc170-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ur/strings.xml b/core/res/res/values-mcc310-mnc170-ur/strings.xml
index ea8b93e..c8b4d65 100644
--- a/core/res/res/values-mcc310-mnc170-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ur/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (3173546391131606065) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-uz/strings.xml b/core/res/res/values-mcc310-mnc170-uz/strings.xml
index 0bb3f52..9bfecfd 100644
--- a/core/res/res/values-mcc310-mnc170-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-vi/strings.xml b/core/res/res/values-mcc310-mnc170-vi/strings.xml
index a37f48f..ad87648 100644
--- a/core/res/res/values-mcc310-mnc170-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml
index f072b28..de68fe1 100644
--- a/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml
index db14b90..5fd10b3 100644
--- a/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml
index db14b90..cb19625 100644
--- a/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-zu/strings.xml b/core/res/res/values-mcc310-mnc170-zu/strings.xml
index 282f403..26890e4e 100644
--- a/core/res/res/values-mcc310-mnc170-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170/strings.xml b/core/res/res/values-mcc310-mnc170/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc170/strings.xml
+++ b/core/res/res/values-mcc310-mnc170/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-af/strings.xml b/core/res/res/values-mcc310-mnc280-af/strings.xml
index a761881..b143077 100644
--- a/core/res/res/values-mcc310-mnc280-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-am/strings.xml b/core/res/res/values-mcc310-mnc280-am/strings.xml
index 6750a71..ffbb1cc 100644
--- a/core/res/res/values-mcc310-mnc280-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ar/strings.xml b/core/res/res/values-mcc310-mnc280-ar/strings.xml
index a77d78e..c7c03a5 100644
--- a/core/res/res/values-mcc310-mnc280-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-az/strings.xml b/core/res/res/values-mcc310-mnc280-az/strings.xml
index b7ee114..7fb788a 100644
--- a/core/res/res/values-mcc310-mnc280-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml
index 0c78b5e..cd78afa 100644
--- a/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM kartica nije podešena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-be/strings.xml b/core/res/res/values-mcc310-mnc280-be/strings.xml
index 3ee9ad9..7da834b 100644
--- a/core/res/res/values-mcc310-mnc280-be/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-be/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-карты няма MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-карта не дапускаецца MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Тэлефон не дапускаецца MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-bg/strings.xml b/core/res/res/values-mcc310-mnc280-bg/strings.xml
index a320898..7b0fac1 100644
--- a/core/res/res/values-mcc310-mnc280-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-bn/strings.xml b/core/res/res/values-mcc310-mnc280-bn/strings.xml
index dc950a7..af3bfa9 100644
--- a/core/res/res/values-mcc310-mnc280-bn/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-bn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"সিমের অনুমতি নেই MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-bs/strings.xml b/core/res/res/values-mcc310-mnc280-bs/strings.xml
index d61fad8..5259a9a 100644
--- a/core/res/res/values-mcc310-mnc280-bs/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-bs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM kartica nije dodijeljena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ca/strings.xml b/core/res/res/values-mcc310-mnc280-ca/strings.xml
index 9a9e309..061c74c 100644
--- a/core/res/res/values-mcc310-mnc280-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-cs/strings.xml b/core/res/res/values-mcc310-mnc280-cs/strings.xml
index 99e2bdb..422d205 100644
--- a/core/res/res/values-mcc310-mnc280-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-da/strings.xml b/core/res/res/values-mcc310-mnc280-da/strings.xml
index 4f444a1..180c523 100644
--- a/core/res/res/values-mcc310-mnc280-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-de/strings.xml b/core/res/res/values-mcc310-mnc280-de/strings.xml
index 063c75b..0ca30c9 100644
--- a/core/res/res/values-mcc310-mnc280-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-el/strings.xml b/core/res/res/values-mcc310-mnc280-el/strings.xml
index 1161a7d..494e53b 100644
--- a/core/res/res/values-mcc310-mnc280-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml
index e9c9eba..c7e6a34 100644
--- a/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rCA/strings.xml b/core/res/res/values-mcc310-mnc280-en-rCA/strings.xml
index e9c9eba..c7e6a34 100644
--- a/core/res/res/values-mcc310-mnc280-en-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-en-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml
index e9c9eba..c7e6a34 100644
--- a/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml
index e9c9eba..c7e6a34 100644
--- a/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rXC/strings.xml b/core/res/res/values-mcc310-mnc280-en-rXC/strings.xml
index 83640ae..7200c69 100644
--- a/core/res/res/values-mcc310-mnc280-en-rXC/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-en-rXC/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‏‎SIM not provisioned MM#2‎‏‎‎‏‎"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎SIM not allowed MM#3‎‏‎‎‏‎"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml
index 86ad4fd..00feb92 100644
--- a/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-es/strings.xml b/core/res/res/values-mcc310-mnc280-es/strings.xml
index 2c7aa93..27945c8 100644
--- a/core/res/res/values-mcc310-mnc280-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-et/strings.xml b/core/res/res/values-mcc310-mnc280-et/strings.xml
index 7305d18..aa127fa 100644
--- a/core/res/res/values-mcc310-mnc280-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-eu/strings.xml b/core/res/res/values-mcc310-mnc280-eu/strings.xml
index 3c7296d..eec8d90 100644
--- a/core/res/res/values-mcc310-mnc280-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-fa/strings.xml b/core/res/res/values-mcc310-mnc280-fa/strings.xml
index cd7ce85..219299c 100644
--- a/core/res/res/values-mcc310-mnc280-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-fi/strings.xml b/core/res/res/values-mcc310-mnc280-fi/strings.xml
index b2ccc50..a21613f 100644
--- a/core/res/res/values-mcc310-mnc280-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml
index 29bb9a0..c5f913f 100644
--- a/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-fr/strings.xml b/core/res/res/values-mcc310-mnc280-fr/strings.xml
index ce2f931..5b6ec9d 100644
--- a/core/res/res/values-mcc310-mnc280-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-gl/strings.xml b/core/res/res/values-mcc310-mnc280-gl/strings.xml
index e941341..0a05c51 100644
--- a/core/res/res/values-mcc310-mnc280-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-gu/strings.xml b/core/res/res/values-mcc310-mnc280-gu/strings.xml
index a3763be..eeedc50 100644
--- a/core/res/res/values-mcc310-mnc280-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-gu/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-hi/strings.xml b/core/res/res/values-mcc310-mnc280-hi/strings.xml
index ce866af..d759d66 100644
--- a/core/res/res/values-mcc310-mnc280-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-hi/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM की अनुमति नहीं है MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-hr/strings.xml b/core/res/res/values-mcc310-mnc280-hr/strings.xml
index 0021474..e6f9abd 100644
--- a/core/res/res/values-mcc310-mnc280-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-hu/strings.xml b/core/res/res/values-mcc310-mnc280-hu/strings.xml
index 864faff..e673aea 100644
--- a/core/res/res/values-mcc310-mnc280-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-hy/strings.xml b/core/res/res/values-mcc310-mnc280-hy/strings.xml
index 6d027c3..b9f59e0 100644
--- a/core/res/res/values-mcc310-mnc280-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-in/strings.xml b/core/res/res/values-mcc310-mnc280-in/strings.xml
index a4f3486..23e60fa 100644
--- a/core/res/res/values-mcc310-mnc280-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-is/strings.xml b/core/res/res/values-mcc310-mnc280-is/strings.xml
index 30bbea4..56034d0 100644
--- a/core/res/res/values-mcc310-mnc280-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-it/strings.xml b/core/res/res/values-mcc310-mnc280-it/strings.xml
index f83921b..b3d34cf 100644
--- a/core/res/res/values-mcc310-mnc280-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-iw/strings.xml b/core/res/res/values-mcc310-mnc280-iw/strings.xml
index f3f87ff..c718941 100644
--- a/core/res/res/values-mcc310-mnc280-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-iw/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ja/strings.xml b/core/res/res/values-mcc310-mnc280-ja/strings.xml
index a1cfd8b..463fc2e 100644
--- a/core/res/res/values-mcc310-mnc280-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ka/strings.xml b/core/res/res/values-mcc310-mnc280-ka/strings.xml
index 91c434f..942944f 100644
--- a/core/res/res/values-mcc310-mnc280-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-kk/strings.xml b/core/res/res/values-mcc310-mnc280-kk/strings.xml
index 44440d3..3559ee0 100644
--- a/core/res/res/values-mcc310-mnc280-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-km/strings.xml b/core/res/res/values-mcc310-mnc280-km/strings.xml
index a016601..69777dc 100644
--- a/core/res/res/values-mcc310-mnc280-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-kn/strings.xml b/core/res/res/values-mcc310-mnc280-kn/strings.xml
index 1d9e353..540565e 100644
--- a/core/res/res/values-mcc310-mnc280-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-kn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ko/strings.xml b/core/res/res/values-mcc310-mnc280-ko/strings.xml
index e7bb9bb..d6ff696 100644
--- a/core/res/res/values-mcc310-mnc280-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ky/strings.xml b/core/res/res/values-mcc310-mnc280-ky/strings.xml
index 85483c7..9ecbcf2 100644
--- a/core/res/res/values-mcc310-mnc280-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ky/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM карта таанылган жок (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-lo/strings.xml b/core/res/res/values-mcc310-mnc280-lo/strings.xml
index 9415089..f72ece1 100644
--- a/core/res/res/values-mcc310-mnc280-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-lt/strings.xml b/core/res/res/values-mcc310-mnc280-lt/strings.xml
index b5ff1b9..80257df 100644
--- a/core/res/res/values-mcc310-mnc280-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-lv/strings.xml b/core/res/res/values-mcc310-mnc280-lv/strings.xml
index 4034bc1..f6bb072 100644
--- a/core/res/res/values-mcc310-mnc280-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-mk/strings.xml b/core/res/res/values-mcc310-mnc280-mk/strings.xml
index a93cb79..f9a7d91 100644
--- a/core/res/res/values-mcc310-mnc280-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ml/strings.xml b/core/res/res/values-mcc310-mnc280-ml/strings.xml
index 4aa7dec..bfcf9ab 100644
--- a/core/res/res/values-mcc310-mnc280-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ml/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-mn/strings.xml b/core/res/res/values-mcc310-mnc280-mn/strings.xml
index 54b8190..2b9d814 100644
--- a/core/res/res/values-mcc310-mnc280-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-mr/strings.xml b/core/res/res/values-mcc310-mnc280-mr/strings.xml
index cb343cb..3518259 100644
--- a/core/res/res/values-mcc310-mnc280-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-mr/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ms/strings.xml b/core/res/res/values-mcc310-mnc280-ms/strings.xml
index 27da747..d140049 100644
--- a/core/res/res/values-mcc310-mnc280-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-my/strings.xml b/core/res/res/values-mcc310-mnc280-my/strings.xml
index 40cdc63..c4ba718 100644
--- a/core/res/res/values-mcc310-mnc280-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-nb/strings.xml b/core/res/res/values-mcc310-mnc280-nb/strings.xml
index 7666c3e..c9eece5 100644
--- a/core/res/res/values-mcc310-mnc280-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ne/strings.xml b/core/res/res/values-mcc310-mnc280-ne/strings.xml
index 8735605..6d89295 100644
--- a/core/res/res/values-mcc310-mnc280-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ne/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM लाई अनुमति छैन MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-nl/strings.xml b/core/res/res/values-mcc310-mnc280-nl/strings.xml
index 7d7bfa7..f6c0e0b 100644
--- a/core/res/res/values-mcc310-mnc280-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-pa/strings.xml b/core/res/res/values-mcc310-mnc280-pa/strings.xml
index 3a65866..d1a1afe 100644
--- a/core/res/res/values-mcc310-mnc280-pa/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-pa/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-pl/strings.xml b/core/res/res/values-mcc310-mnc280-pl/strings.xml
index 52410f4..ee33cf6 100644
--- a/core/res/res/values-mcc310-mnc280-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml
index 03d0efb..f7fb684 100644
--- a/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml
index 03d0efb..1a64f5c 100644
--- a/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-pt/strings.xml b/core/res/res/values-mcc310-mnc280-pt/strings.xml
index 03d0efb..f7fb684 100644
--- a/core/res/res/values-mcc310-mnc280-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ro/strings.xml b/core/res/res/values-mcc310-mnc280-ro/strings.xml
index d60ea0c..5ed83b3 100644
--- a/core/res/res/values-mcc310-mnc280-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ru/strings.xml b/core/res/res/values-mcc310-mnc280-ru/strings.xml
index 308c353..c9e22bb 100644
--- a/core/res/res/values-mcc310-mnc280-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-si/strings.xml b/core/res/res/values-mcc310-mnc280-si/strings.xml
index 5bd6d1f..fa5b3c0 100644
--- a/core/res/res/values-mcc310-mnc280-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sk/strings.xml b/core/res/res/values-mcc310-mnc280-sk/strings.xml
index 4098ac7..b116331 100644
--- a/core/res/res/values-mcc310-mnc280-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sl/strings.xml b/core/res/res/values-mcc310-mnc280-sl/strings.xml
index faa78ad..1a75b94 100644
--- a/core/res/res/values-mcc310-mnc280-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sq/strings.xml b/core/res/res/values-mcc310-mnc280-sq/strings.xml
index 48fba2d..54072e2 100644
--- a/core/res/res/values-mcc310-mnc280-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sr/strings.xml b/core/res/res/values-mcc310-mnc280-sr/strings.xml
index 30c9df3..f4591b6 100644
--- a/core/res/res/values-mcc310-mnc280-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sv/strings.xml b/core/res/res/values-mcc310-mnc280-sv/strings.xml
index cb5b9f32..294d762 100644
--- a/core/res/res/values-mcc310-mnc280-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sw/strings.xml b/core/res/res/values-mcc310-mnc280-sw/strings.xml
index 15a1a36..4912340 100644
--- a/core/res/res/values-mcc310-mnc280-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ta/strings.xml b/core/res/res/values-mcc310-mnc280-ta/strings.xml
index c3911d4..19eeffa 100644
--- a/core/res/res/values-mcc310-mnc280-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ta/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-te/strings.xml b/core/res/res/values-mcc310-mnc280-te/strings.xml
index f5cabad..75d5b73 100644
--- a/core/res/res/values-mcc310-mnc280-te/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-te/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM MM#2ని సక్రియం చేయలేదు"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ఫోన్ అనుమతించబడదు MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-th/strings.xml b/core/res/res/values-mcc310-mnc280-th/strings.xml
index 9810ba6..2312bb4 100644
--- a/core/res/res/values-mcc310-mnc280-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-tl/strings.xml b/core/res/res/values-mcc310-mnc280-tl/strings.xml
index 600ad05..8c05e82 100644
--- a/core/res/res/values-mcc310-mnc280-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-tr/strings.xml b/core/res/res/values-mcc310-mnc280-tr/strings.xml
index ea90bdb..4e9cc2c 100644
--- a/core/res/res/values-mcc310-mnc280-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-uk/strings.xml b/core/res/res/values-mcc310-mnc280-uk/strings.xml
index 68a34fd..aa500d6 100644
--- a/core/res/res/values-mcc310-mnc280-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ur/strings.xml b/core/res/res/values-mcc310-mnc280-ur/strings.xml
index d61a5dc..50f5d01 100644
--- a/core/res/res/values-mcc310-mnc280-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ur/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (822496463303720579) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-uz/strings.xml b/core/res/res/values-mcc310-mnc280-uz/strings.xml
index 324d364..9110cfc 100644
--- a/core/res/res/values-mcc310-mnc280-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-vi/strings.xml b/core/res/res/values-mcc310-mnc280-vi/strings.xml
index 6806e39..444f882 100644
--- a/core/res/res/values-mcc310-mnc280-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml
index add3f920..aa85594 100644
--- a/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml
index 856297c..c986d5d 100644
--- a/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml
index 856297c..720d097 100644
--- a/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-zu/strings.xml b/core/res/res/values-mcc310-mnc280-zu/strings.xml
index 6c5147c..a198302 100644
--- a/core/res/res/values-mcc310-mnc280-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280/strings.xml b/core/res/res/values-mcc310-mnc280/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc280/strings.xml
+++ b/core/res/res/values-mcc310-mnc280/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-af/strings.xml b/core/res/res/values-mcc310-mnc410-af/strings.xml
index 81688f1..7aea163 100644
--- a/core/res/res/values-mcc310-mnc410-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-am/strings.xml b/core/res/res/values-mcc310-mnc410-am/strings.xml
index 176a628..b5f5356 100644
--- a/core/res/res/values-mcc310-mnc410-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ar/strings.xml b/core/res/res/values-mcc310-mnc410-ar/strings.xml
index 884e18e..829ea43 100644
--- a/core/res/res/values-mcc310-mnc410-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-az/strings.xml b/core/res/res/values-mcc310-mnc410-az/strings.xml
index 178451c..497f37a 100644
--- a/core/res/res/values-mcc310-mnc410-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml
index 8981a35..95b9e00 100644
--- a/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM kartica nije podešena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-be/strings.xml b/core/res/res/values-mcc310-mnc410-be/strings.xml
index 8ae8639..291eb12 100644
--- a/core/res/res/values-mcc310-mnc410-be/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-be/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-карты няма MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-карта не дапускаецца MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Тэлефон не дапускаецца MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-bg/strings.xml b/core/res/res/values-mcc310-mnc410-bg/strings.xml
index fc6f3e5..9ea8ddf 100644
--- a/core/res/res/values-mcc310-mnc410-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-bn/strings.xml b/core/res/res/values-mcc310-mnc410-bn/strings.xml
index e42a375..ae051f8 100644
--- a/core/res/res/values-mcc310-mnc410-bn/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-bn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"সিমের অনুমতি নেই MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-bs/strings.xml b/core/res/res/values-mcc310-mnc410-bs/strings.xml
index 4d7da3a..550a5ca 100644
--- a/core/res/res/values-mcc310-mnc410-bs/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-bs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM kartica nije dodijeljena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ca/strings.xml b/core/res/res/values-mcc310-mnc410-ca/strings.xml
index 19ab945b..2827e20 100644
--- a/core/res/res/values-mcc310-mnc410-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-cs/strings.xml b/core/res/res/values-mcc310-mnc410-cs/strings.xml
index 3e36325..22610b0 100644
--- a/core/res/res/values-mcc310-mnc410-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-da/strings.xml b/core/res/res/values-mcc310-mnc410-da/strings.xml
index e99ab57..38c47b3 100644
--- a/core/res/res/values-mcc310-mnc410-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-de/strings.xml b/core/res/res/values-mcc310-mnc410-de/strings.xml
index c5f64f4..ed8cd5d 100644
--- a/core/res/res/values-mcc310-mnc410-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-el/strings.xml b/core/res/res/values-mcc310-mnc410-el/strings.xml
index 128d1bf..9c9bafa 100644
--- a/core/res/res/values-mcc310-mnc410-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml
index eb56351..5258201 100644
--- a/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rCA/strings.xml b/core/res/res/values-mcc310-mnc410-en-rCA/strings.xml
index eb56351..5258201 100644
--- a/core/res/res/values-mcc310-mnc410-en-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-en-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml
index eb56351..5258201 100644
--- a/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml
index eb56351..5258201 100644
--- a/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rXC/strings.xml b/core/res/res/values-mcc310-mnc410-en-rXC/strings.xml
index 4799e38..32a723f 100644
--- a/core/res/res/values-mcc310-mnc410-en-rXC/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-en-rXC/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎SIM not provisioned MM#2‎‏‎‎‏‎"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‎SIM not allowed MM#3‎‏‎‎‏‎"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml
index 85b0344..d9748af 100644
--- a/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-es/strings.xml b/core/res/res/values-mcc310-mnc410-es/strings.xml
index 248069e..0459bbb 100644
--- a/core/res/res/values-mcc310-mnc410-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-et/strings.xml b/core/res/res/values-mcc310-mnc410-et/strings.xml
index 6ef7802..02f60b3 100644
--- a/core/res/res/values-mcc310-mnc410-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-eu/strings.xml b/core/res/res/values-mcc310-mnc410-eu/strings.xml
index 966511b..ef42cb9 100644
--- a/core/res/res/values-mcc310-mnc410-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-fa/strings.xml b/core/res/res/values-mcc310-mnc410-fa/strings.xml
index 82f6272..e9dcc07 100644
--- a/core/res/res/values-mcc310-mnc410-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-fi/strings.xml b/core/res/res/values-mcc310-mnc410-fi/strings.xml
index c5a4ef6..38485c3 100644
--- a/core/res/res/values-mcc310-mnc410-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml
index cec2491..fe8c960 100644
--- a/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-fr/strings.xml b/core/res/res/values-mcc310-mnc410-fr/strings.xml
index f715e71..c0fb381 100644
--- a/core/res/res/values-mcc310-mnc410-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-gl/strings.xml b/core/res/res/values-mcc310-mnc410-gl/strings.xml
index c3aba8e..56ce287 100644
--- a/core/res/res/values-mcc310-mnc410-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-gu/strings.xml b/core/res/res/values-mcc310-mnc410-gu/strings.xml
index 26898f4..8255843 100644
--- a/core/res/res/values-mcc310-mnc410-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-gu/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-hi/strings.xml b/core/res/res/values-mcc310-mnc410-hi/strings.xml
index a01845a..2f02ea3 100644
--- a/core/res/res/values-mcc310-mnc410-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-hi/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM की अनुमति नहीं है MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-hr/strings.xml b/core/res/res/values-mcc310-mnc410-hr/strings.xml
index 47062c4..0ee4ae6 100644
--- a/core/res/res/values-mcc310-mnc410-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-hu/strings.xml b/core/res/res/values-mcc310-mnc410-hu/strings.xml
index 194d865..8abc27d 100644
--- a/core/res/res/values-mcc310-mnc410-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-hy/strings.xml b/core/res/res/values-mcc310-mnc410-hy/strings.xml
index 85129cc..79bc531 100644
--- a/core/res/res/values-mcc310-mnc410-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-in/strings.xml b/core/res/res/values-mcc310-mnc410-in/strings.xml
index c065221..5750563 100644
--- a/core/res/res/values-mcc310-mnc410-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-is/strings.xml b/core/res/res/values-mcc310-mnc410-is/strings.xml
index a40a643..a786285 100644
--- a/core/res/res/values-mcc310-mnc410-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-it/strings.xml b/core/res/res/values-mcc310-mnc410-it/strings.xml
index ab5c731..135d39d 100644
--- a/core/res/res/values-mcc310-mnc410-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-iw/strings.xml b/core/res/res/values-mcc310-mnc410-iw/strings.xml
index b675f64..5ab1bea 100644
--- a/core/res/res/values-mcc310-mnc410-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-iw/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ja/strings.xml b/core/res/res/values-mcc310-mnc410-ja/strings.xml
index 1961a75b..e0e98e3 100644
--- a/core/res/res/values-mcc310-mnc410-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ka/strings.xml b/core/res/res/values-mcc310-mnc410-ka/strings.xml
index 5216e8f..63af51c 100644
--- a/core/res/res/values-mcc310-mnc410-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-kk/strings.xml b/core/res/res/values-mcc310-mnc410-kk/strings.xml
index 137c73a..5a52be2 100644
--- a/core/res/res/values-mcc310-mnc410-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-km/strings.xml b/core/res/res/values-mcc310-mnc410-km/strings.xml
index 94babe1..809ffd1 100644
--- a/core/res/res/values-mcc310-mnc410-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-kn/strings.xml b/core/res/res/values-mcc310-mnc410-kn/strings.xml
index b003dcc..cba3f3d 100644
--- a/core/res/res/values-mcc310-mnc410-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-kn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ko/strings.xml b/core/res/res/values-mcc310-mnc410-ko/strings.xml
index 7824d1e6..dc1a9a5 100644
--- a/core/res/res/values-mcc310-mnc410-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ky/strings.xml b/core/res/res/values-mcc310-mnc410-ky/strings.xml
index 9e4f23e..05314ed 100644
--- a/core/res/res/values-mcc310-mnc410-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ky/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM карта таанылган жок (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-lo/strings.xml b/core/res/res/values-mcc310-mnc410-lo/strings.xml
index 9684e7a..9e095ba 100644
--- a/core/res/res/values-mcc310-mnc410-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-lt/strings.xml b/core/res/res/values-mcc310-mnc410-lt/strings.xml
index c4a646a..72b9a08 100644
--- a/core/res/res/values-mcc310-mnc410-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-lv/strings.xml b/core/res/res/values-mcc310-mnc410-lv/strings.xml
index e95d62b..e3c04f8 100644
--- a/core/res/res/values-mcc310-mnc410-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-mk/strings.xml b/core/res/res/values-mcc310-mnc410-mk/strings.xml
index 76bba96..d34261d 100644
--- a/core/res/res/values-mcc310-mnc410-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ml/strings.xml b/core/res/res/values-mcc310-mnc410-ml/strings.xml
index 94436bd..4f8bdc0 100644
--- a/core/res/res/values-mcc310-mnc410-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ml/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-mn/strings.xml b/core/res/res/values-mcc310-mnc410-mn/strings.xml
index 2667aab..70cc206 100644
--- a/core/res/res/values-mcc310-mnc410-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-mr/strings.xml b/core/res/res/values-mcc310-mnc410-mr/strings.xml
index e7b0644..1280ed6 100644
--- a/core/res/res/values-mcc310-mnc410-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-mr/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ms/strings.xml b/core/res/res/values-mcc310-mnc410-ms/strings.xml
index 85b8621..b896e67 100644
--- a/core/res/res/values-mcc310-mnc410-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-my/strings.xml b/core/res/res/values-mcc310-mnc410-my/strings.xml
index faa80ec..07a2967 100644
--- a/core/res/res/values-mcc310-mnc410-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-nb/strings.xml b/core/res/res/values-mcc310-mnc410-nb/strings.xml
index 79be7af..4f6e125 100644
--- a/core/res/res/values-mcc310-mnc410-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ne/strings.xml b/core/res/res/values-mcc310-mnc410-ne/strings.xml
index e270c7c..5ff0ee3 100644
--- a/core/res/res/values-mcc310-mnc410-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ne/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM लाई अनुमति छैन MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-nl/strings.xml b/core/res/res/values-mcc310-mnc410-nl/strings.xml
index 2995beb..7da7fab 100644
--- a/core/res/res/values-mcc310-mnc410-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-pa/strings.xml b/core/res/res/values-mcc310-mnc410-pa/strings.xml
index 70195f1..9aafd74 100644
--- a/core/res/res/values-mcc310-mnc410-pa/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-pa/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-pl/strings.xml b/core/res/res/values-mcc310-mnc410-pl/strings.xml
index 8677ad6..f74650f 100644
--- a/core/res/res/values-mcc310-mnc410-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml
index 4f41e5e..f6bfc67 100644
--- a/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml
index 4f41e5e..5457416 100644
--- a/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-pt/strings.xml b/core/res/res/values-mcc310-mnc410-pt/strings.xml
index 4f41e5e..f6bfc67 100644
--- a/core/res/res/values-mcc310-mnc410-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ro/strings.xml b/core/res/res/values-mcc310-mnc410-ro/strings.xml
index fea0609..0fc9400 100644
--- a/core/res/res/values-mcc310-mnc410-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ru/strings.xml b/core/res/res/values-mcc310-mnc410-ru/strings.xml
index a00e59c..8702e83 100644
--- a/core/res/res/values-mcc310-mnc410-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-si/strings.xml b/core/res/res/values-mcc310-mnc410-si/strings.xml
index 8f66f3d..cddc168 100644
--- a/core/res/res/values-mcc310-mnc410-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sk/strings.xml b/core/res/res/values-mcc310-mnc410-sk/strings.xml
index e4d4bc6..354b138 100644
--- a/core/res/res/values-mcc310-mnc410-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sl/strings.xml b/core/res/res/values-mcc310-mnc410-sl/strings.xml
index 2d03b04..d65d619 100644
--- a/core/res/res/values-mcc310-mnc410-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sq/strings.xml b/core/res/res/values-mcc310-mnc410-sq/strings.xml
index 51626d7..95ec705 100644
--- a/core/res/res/values-mcc310-mnc410-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sr/strings.xml b/core/res/res/values-mcc310-mnc410-sr/strings.xml
index b4a9006..66fe4e7 100644
--- a/core/res/res/values-mcc310-mnc410-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sv/strings.xml b/core/res/res/values-mcc310-mnc410-sv/strings.xml
index c270b04..77e0829 100644
--- a/core/res/res/values-mcc310-mnc410-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sw/strings.xml b/core/res/res/values-mcc310-mnc410-sw/strings.xml
index a6e6018..50c2e74 100644
--- a/core/res/res/values-mcc310-mnc410-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ta/strings.xml b/core/res/res/values-mcc310-mnc410-ta/strings.xml
index 4ac46ce..8f161ca 100644
--- a/core/res/res/values-mcc310-mnc410-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ta/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-te/strings.xml b/core/res/res/values-mcc310-mnc410-te/strings.xml
index 5b56435..133b332 100644
--- a/core/res/res/values-mcc310-mnc410-te/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-te/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM MM#2ని సక్రియం చేయలేదు"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ఫోన్ అనుమతించబడదు MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-th/strings.xml b/core/res/res/values-mcc310-mnc410-th/strings.xml
index cf51029..0b728bf 100644
--- a/core/res/res/values-mcc310-mnc410-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-tl/strings.xml b/core/res/res/values-mcc310-mnc410-tl/strings.xml
index b2aa68a..3bf972d 100644
--- a/core/res/res/values-mcc310-mnc410-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-tr/strings.xml b/core/res/res/values-mcc310-mnc410-tr/strings.xml
index 9e5c38e..34ce123 100644
--- a/core/res/res/values-mcc310-mnc410-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-uk/strings.xml b/core/res/res/values-mcc310-mnc410-uk/strings.xml
index 5d74f80..9d8ccb2 100644
--- a/core/res/res/values-mcc310-mnc410-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ur/strings.xml b/core/res/res/values-mcc310-mnc410-ur/strings.xml
index 8cf16e4..c14dfd1 100644
--- a/core/res/res/values-mcc310-mnc410-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ur/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (4477688981805467729) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-uz/strings.xml b/core/res/res/values-mcc310-mnc410-uz/strings.xml
index 4618525..fdfad9b 100644
--- a/core/res/res/values-mcc310-mnc410-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-vi/strings.xml b/core/res/res/values-mcc310-mnc410-vi/strings.xml
index e6fc334..77cff43 100644
--- a/core/res/res/values-mcc310-mnc410-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml
index a00316a..ec8d371 100644
--- a/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml
index 66a622e..7f54efb 100644
--- a/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml
index 66a622e..a0aaaa5 100644
--- a/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-zu/strings.xml b/core/res/res/values-mcc310-mnc410-zu/strings.xml
index a52049f..67cc1ac 100644
--- a/core/res/res/values-mcc310-mnc410-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410/strings.xml b/core/res/res/values-mcc310-mnc410/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc410/strings.xml
+++ b/core/res/res/values-mcc310-mnc410/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-af/strings.xml b/core/res/res/values-mcc310-mnc560-af/strings.xml
index ecbb954..87f698c 100644
--- a/core/res/res/values-mcc310-mnc560-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-am/strings.xml b/core/res/res/values-mcc310-mnc560-am/strings.xml
index 297c059..c1f8350 100644
--- a/core/res/res/values-mcc310-mnc560-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ar/strings.xml b/core/res/res/values-mcc310-mnc560-ar/strings.xml
index 12a06fa..d5c684f 100644
--- a/core/res/res/values-mcc310-mnc560-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-az/strings.xml b/core/res/res/values-mcc310-mnc560-az/strings.xml
index 9acc2c1..1edff5e 100644
--- a/core/res/res/values-mcc310-mnc560-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml
index 616f871..d362bad 100644
--- a/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM kartica nije podešena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-be/strings.xml b/core/res/res/values-mcc310-mnc560-be/strings.xml
index 0e70cf2..3f62d3c 100644
--- a/core/res/res/values-mcc310-mnc560-be/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-be/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-карты няма MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-карта не дапускаецца MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Тэлефон не дапускаецца MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-bg/strings.xml b/core/res/res/values-mcc310-mnc560-bg/strings.xml
index 49c2d2f..98c362d 100644
--- a/core/res/res/values-mcc310-mnc560-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-bn/strings.xml b/core/res/res/values-mcc310-mnc560-bn/strings.xml
index 438791d..ce04a90 100644
--- a/core/res/res/values-mcc310-mnc560-bn/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-bn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"সিমের অনুমতি নেই MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-bs/strings.xml b/core/res/res/values-mcc310-mnc560-bs/strings.xml
index 82046a6..3dccc4be 100644
--- a/core/res/res/values-mcc310-mnc560-bs/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-bs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM kartica nije dodijeljena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ca/strings.xml b/core/res/res/values-mcc310-mnc560-ca/strings.xml
index 1eac589..00fc4ed 100644
--- a/core/res/res/values-mcc310-mnc560-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-cs/strings.xml b/core/res/res/values-mcc310-mnc560-cs/strings.xml
index 4701f99..9a68265 100644
--- a/core/res/res/values-mcc310-mnc560-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-da/strings.xml b/core/res/res/values-mcc310-mnc560-da/strings.xml
index 2c63d87..857e040 100644
--- a/core/res/res/values-mcc310-mnc560-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-de/strings.xml b/core/res/res/values-mcc310-mnc560-de/strings.xml
index e8fec2c..a5d594b 100644
--- a/core/res/res/values-mcc310-mnc560-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-el/strings.xml b/core/res/res/values-mcc310-mnc560-el/strings.xml
index efd81f7..803ecdd 100644
--- a/core/res/res/values-mcc310-mnc560-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml
index c218c64..d24a056 100644
--- a/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rCA/strings.xml b/core/res/res/values-mcc310-mnc560-en-rCA/strings.xml
index c218c64..d24a056 100644
--- a/core/res/res/values-mcc310-mnc560-en-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-en-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml
index c218c64..d24a056 100644
--- a/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml
index c218c64..d24a056 100644
--- a/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rXC/strings.xml b/core/res/res/values-mcc310-mnc560-en-rXC/strings.xml
index 67c05b2..694aa31 100644
--- a/core/res/res/values-mcc310-mnc560-en-rXC/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-en-rXC/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎SIM not provisioned MM#2‎‏‎‎‏‎"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎SIM not allowed MM#3‎‏‎‎‏‎"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml
index 62d61ba..52b2554 100644
--- a/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-es/strings.xml b/core/res/res/values-mcc310-mnc560-es/strings.xml
index dbd71d5..8fb818b 100644
--- a/core/res/res/values-mcc310-mnc560-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-et/strings.xml b/core/res/res/values-mcc310-mnc560-et/strings.xml
index b269ace..1bb5bd5 100644
--- a/core/res/res/values-mcc310-mnc560-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-eu/strings.xml b/core/res/res/values-mcc310-mnc560-eu/strings.xml
index cee0106..1fd51a9 100644
--- a/core/res/res/values-mcc310-mnc560-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-fa/strings.xml b/core/res/res/values-mcc310-mnc560-fa/strings.xml
index b4683c7..d2c8c41 100644
--- a/core/res/res/values-mcc310-mnc560-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-fi/strings.xml b/core/res/res/values-mcc310-mnc560-fi/strings.xml
index 54c80ed..fc7629d 100644
--- a/core/res/res/values-mcc310-mnc560-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml
index 8b6c4ec..246b434 100644
--- a/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-fr/strings.xml b/core/res/res/values-mcc310-mnc560-fr/strings.xml
index b52eaf7..9601bc5 100644
--- a/core/res/res/values-mcc310-mnc560-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-gl/strings.xml b/core/res/res/values-mcc310-mnc560-gl/strings.xml
index a8c04d2..1f78daa 100644
--- a/core/res/res/values-mcc310-mnc560-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-gu/strings.xml b/core/res/res/values-mcc310-mnc560-gu/strings.xml
index c3892da..c7b8101 100644
--- a/core/res/res/values-mcc310-mnc560-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-gu/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-hi/strings.xml b/core/res/res/values-mcc310-mnc560-hi/strings.xml
index 4e07e4f..3d90c2e 100644
--- a/core/res/res/values-mcc310-mnc560-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-hi/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM की अनुमति नहीं है MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-hr/strings.xml b/core/res/res/values-mcc310-mnc560-hr/strings.xml
index dc6653e..f51599c 100644
--- a/core/res/res/values-mcc310-mnc560-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-hu/strings.xml b/core/res/res/values-mcc310-mnc560-hu/strings.xml
index 1a7a6b3..f23dd04 100644
--- a/core/res/res/values-mcc310-mnc560-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-hy/strings.xml b/core/res/res/values-mcc310-mnc560-hy/strings.xml
index c398877..072c0c5 100644
--- a/core/res/res/values-mcc310-mnc560-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-in/strings.xml b/core/res/res/values-mcc310-mnc560-in/strings.xml
index c3c7df3..9b56660 100644
--- a/core/res/res/values-mcc310-mnc560-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-is/strings.xml b/core/res/res/values-mcc310-mnc560-is/strings.xml
index 4a59abd..3ae1361 100644
--- a/core/res/res/values-mcc310-mnc560-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-it/strings.xml b/core/res/res/values-mcc310-mnc560-it/strings.xml
index d2c966c..201e5b3 100644
--- a/core/res/res/values-mcc310-mnc560-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-iw/strings.xml b/core/res/res/values-mcc310-mnc560-iw/strings.xml
index 68f0aa9..942048b 100644
--- a/core/res/res/values-mcc310-mnc560-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-iw/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ja/strings.xml b/core/res/res/values-mcc310-mnc560-ja/strings.xml
index 0429996..244c93a 100644
--- a/core/res/res/values-mcc310-mnc560-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ka/strings.xml b/core/res/res/values-mcc310-mnc560-ka/strings.xml
index b0371f0..c89674b 100644
--- a/core/res/res/values-mcc310-mnc560-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-kk/strings.xml b/core/res/res/values-mcc310-mnc560-kk/strings.xml
index 2015f8c..33aa902 100644
--- a/core/res/res/values-mcc310-mnc560-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-km/strings.xml b/core/res/res/values-mcc310-mnc560-km/strings.xml
index a13ca7d..b01e283 100644
--- a/core/res/res/values-mcc310-mnc560-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-kn/strings.xml b/core/res/res/values-mcc310-mnc560-kn/strings.xml
index da75904..da7c0d0 100644
--- a/core/res/res/values-mcc310-mnc560-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-kn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ko/strings.xml b/core/res/res/values-mcc310-mnc560-ko/strings.xml
index ee71a09c..74d6064 100644
--- a/core/res/res/values-mcc310-mnc560-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ky/strings.xml b/core/res/res/values-mcc310-mnc560-ky/strings.xml
index 856bebc..75e4794 100644
--- a/core/res/res/values-mcc310-mnc560-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ky/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM карта таанылган жок (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-lo/strings.xml b/core/res/res/values-mcc310-mnc560-lo/strings.xml
index 702470e..9244031 100644
--- a/core/res/res/values-mcc310-mnc560-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-lt/strings.xml b/core/res/res/values-mcc310-mnc560-lt/strings.xml
index c3c5a9e..8ced4c0 100644
--- a/core/res/res/values-mcc310-mnc560-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-lv/strings.xml b/core/res/res/values-mcc310-mnc560-lv/strings.xml
index dcf7805..fc565d6 100644
--- a/core/res/res/values-mcc310-mnc560-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-mk/strings.xml b/core/res/res/values-mcc310-mnc560-mk/strings.xml
index cf0ae7e..6d159f4 100644
--- a/core/res/res/values-mcc310-mnc560-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ml/strings.xml b/core/res/res/values-mcc310-mnc560-ml/strings.xml
index fb506bf..47acda4 100644
--- a/core/res/res/values-mcc310-mnc560-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ml/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-mn/strings.xml b/core/res/res/values-mcc310-mnc560-mn/strings.xml
index 0bf1599..1d01e8c 100644
--- a/core/res/res/values-mcc310-mnc560-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-mr/strings.xml b/core/res/res/values-mcc310-mnc560-mr/strings.xml
index 69e81ad..8c81a41 100644
--- a/core/res/res/values-mcc310-mnc560-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-mr/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ms/strings.xml b/core/res/res/values-mcc310-mnc560-ms/strings.xml
index cd0aed7..3c5c712 100644
--- a/core/res/res/values-mcc310-mnc560-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-my/strings.xml b/core/res/res/values-mcc310-mnc560-my/strings.xml
index 58fba87..00600be 100644
--- a/core/res/res/values-mcc310-mnc560-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-nb/strings.xml b/core/res/res/values-mcc310-mnc560-nb/strings.xml
index bc90ae1..ce9dd874 100644
--- a/core/res/res/values-mcc310-mnc560-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ne/strings.xml b/core/res/res/values-mcc310-mnc560-ne/strings.xml
index 75c493d..eb6cedb 100644
--- a/core/res/res/values-mcc310-mnc560-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ne/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM लाई अनुमति छैन MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-nl/strings.xml b/core/res/res/values-mcc310-mnc560-nl/strings.xml
index 7241627..eadbb84 100644
--- a/core/res/res/values-mcc310-mnc560-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-pa/strings.xml b/core/res/res/values-mcc310-mnc560-pa/strings.xml
index a2b76be..090d307 100644
--- a/core/res/res/values-mcc310-mnc560-pa/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-pa/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-pl/strings.xml b/core/res/res/values-mcc310-mnc560-pl/strings.xml
index f844db6..0f4b474 100644
--- a/core/res/res/values-mcc310-mnc560-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml
index 4c10ef9..fba400c 100644
--- a/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml
index 4c10ef9..991627c 100644
--- a/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-pt/strings.xml b/core/res/res/values-mcc310-mnc560-pt/strings.xml
index 4c10ef9..fba400c 100644
--- a/core/res/res/values-mcc310-mnc560-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ro/strings.xml b/core/res/res/values-mcc310-mnc560-ro/strings.xml
index e24b74c..1e6c63a 100644
--- a/core/res/res/values-mcc310-mnc560-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ru/strings.xml b/core/res/res/values-mcc310-mnc560-ru/strings.xml
index 35bf36f..948c8c8 100644
--- a/core/res/res/values-mcc310-mnc560-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-si/strings.xml b/core/res/res/values-mcc310-mnc560-si/strings.xml
index 4c60ce4..b65d067 100644
--- a/core/res/res/values-mcc310-mnc560-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sk/strings.xml b/core/res/res/values-mcc310-mnc560-sk/strings.xml
index ad4aba4..cae65ff 100644
--- a/core/res/res/values-mcc310-mnc560-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sl/strings.xml b/core/res/res/values-mcc310-mnc560-sl/strings.xml
index 7855987..15c495e 100644
--- a/core/res/res/values-mcc310-mnc560-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sq/strings.xml b/core/res/res/values-mcc310-mnc560-sq/strings.xml
index 527430e..a554e81 100644
--- a/core/res/res/values-mcc310-mnc560-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sr/strings.xml b/core/res/res/values-mcc310-mnc560-sr/strings.xml
index ec5a2b6..3a2d6c0 100644
--- a/core/res/res/values-mcc310-mnc560-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sv/strings.xml b/core/res/res/values-mcc310-mnc560-sv/strings.xml
index d113989..ef712b4 100644
--- a/core/res/res/values-mcc310-mnc560-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sw/strings.xml b/core/res/res/values-mcc310-mnc560-sw/strings.xml
index 4e3df8b..2f989a7 100644
--- a/core/res/res/values-mcc310-mnc560-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ta/strings.xml b/core/res/res/values-mcc310-mnc560-ta/strings.xml
index 78f8243..45c2acf 100644
--- a/core/res/res/values-mcc310-mnc560-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ta/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-te/strings.xml b/core/res/res/values-mcc310-mnc560-te/strings.xml
index aeda941..f5e09ba 100644
--- a/core/res/res/values-mcc310-mnc560-te/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-te/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM MM#2ని సక్రియం చేయలేదు"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ఫోన్ అనుమతించబడదు MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-th/strings.xml b/core/res/res/values-mcc310-mnc560-th/strings.xml
index 7896973..881f797 100644
--- a/core/res/res/values-mcc310-mnc560-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-tl/strings.xml b/core/res/res/values-mcc310-mnc560-tl/strings.xml
index ac87cb5..2e32d53 100644
--- a/core/res/res/values-mcc310-mnc560-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-tr/strings.xml b/core/res/res/values-mcc310-mnc560-tr/strings.xml
index 5ea1d80..2b41e2c 100644
--- a/core/res/res/values-mcc310-mnc560-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-uk/strings.xml b/core/res/res/values-mcc310-mnc560-uk/strings.xml
index 7ee6b88..bd75240 100644
--- a/core/res/res/values-mcc310-mnc560-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ur/strings.xml b/core/res/res/values-mcc310-mnc560-ur/strings.xml
index 609d3e8..3534fdb 100644
--- a/core/res/res/values-mcc310-mnc560-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ur/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (7030488670186895244) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-uz/strings.xml b/core/res/res/values-mcc310-mnc560-uz/strings.xml
index 4157041..92b86e1 100644
--- a/core/res/res/values-mcc310-mnc560-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-vi/strings.xml b/core/res/res/values-mcc310-mnc560-vi/strings.xml
index b2284e1..7023d51 100644
--- a/core/res/res/values-mcc310-mnc560-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml
index 050ea01..bf168bd 100644
--- a/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml
index 43cfc01..ea8dcab 100644
--- a/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml
index 43cfc01..3674ee2 100644
--- a/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-zu/strings.xml b/core/res/res/values-mcc310-mnc560-zu/strings.xml
index e1b7abb..7b17fed 100644
--- a/core/res/res/values-mcc310-mnc560-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560/strings.xml b/core/res/res/values-mcc310-mnc560/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc560/strings.xml
+++ b/core/res/res/values-mcc310-mnc560/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-af/strings.xml b/core/res/res/values-mcc310-mnc950-af/strings.xml
index 19ae78d..95b73b9 100644
--- a/core/res/res/values-mcc310-mnc950-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-am/strings.xml b/core/res/res/values-mcc310-mnc950-am/strings.xml
index e81745d..ca5d603 100644
--- a/core/res/res/values-mcc310-mnc950-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ar/strings.xml b/core/res/res/values-mcc310-mnc950-ar/strings.xml
index 1aab01c..bc2248b 100644
--- a/core/res/res/values-mcc310-mnc950-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-az/strings.xml b/core/res/res/values-mcc310-mnc950-az/strings.xml
index 26d91ef..ceb15ea 100644
--- a/core/res/res/values-mcc310-mnc950-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml
index 44c5d19..def86da 100644
--- a/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM kartica nije podešena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-be/strings.xml b/core/res/res/values-mcc310-mnc950-be/strings.xml
index 2bae8c4..4dd80ff 100644
--- a/core/res/res/values-mcc310-mnc950-be/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-be/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-карты няма MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-карта не дапускаецца MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Тэлефон не дапускаецца MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-bg/strings.xml b/core/res/res/values-mcc310-mnc950-bg/strings.xml
index 761b439..5342fa8 100644
--- a/core/res/res/values-mcc310-mnc950-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-bn/strings.xml b/core/res/res/values-mcc310-mnc950-bn/strings.xml
index 32ba8b8..e4d0f5f 100644
--- a/core/res/res/values-mcc310-mnc950-bn/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-bn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"সিমের অনুমতি নেই MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-bs/strings.xml b/core/res/res/values-mcc310-mnc950-bs/strings.xml
index b06b586..4fbaa3c 100644
--- a/core/res/res/values-mcc310-mnc950-bs/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-bs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM kartica nije dodijeljena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ca/strings.xml b/core/res/res/values-mcc310-mnc950-ca/strings.xml
index 9b77ce7..adb12e8 100644
--- a/core/res/res/values-mcc310-mnc950-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-cs/strings.xml b/core/res/res/values-mcc310-mnc950-cs/strings.xml
index 3f8b8aa..49cc25f 100644
--- a/core/res/res/values-mcc310-mnc950-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-da/strings.xml b/core/res/res/values-mcc310-mnc950-da/strings.xml
index 6cd8306..e63a586 100644
--- a/core/res/res/values-mcc310-mnc950-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-de/strings.xml b/core/res/res/values-mcc310-mnc950-de/strings.xml
index 70e3068..60d81e6 100644
--- a/core/res/res/values-mcc310-mnc950-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-el/strings.xml b/core/res/res/values-mcc310-mnc950-el/strings.xml
index 1a2542c..bffaa00 100644
--- a/core/res/res/values-mcc310-mnc950-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml
index 7ef6605..d2d137c 100644
--- a/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rCA/strings.xml b/core/res/res/values-mcc310-mnc950-en-rCA/strings.xml
index 7ef6605..d2d137c 100644
--- a/core/res/res/values-mcc310-mnc950-en-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-en-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml
index 7ef6605..d2d137c 100644
--- a/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml
index 7ef6605..d2d137c 100644
--- a/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rXC/strings.xml b/core/res/res/values-mcc310-mnc950-en-rXC/strings.xml
index 243d731..89619c4 100644
--- a/core/res/res/values-mcc310-mnc950-en-rXC/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-en-rXC/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎SIM not provisioned MM#2‎‏‎‎‏‎"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎SIM not allowed MM#3‎‏‎‎‏‎"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml
index 31a863c..d194180 100644
--- a/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-es/strings.xml b/core/res/res/values-mcc310-mnc950-es/strings.xml
index ba8c78b..bbb0acf 100644
--- a/core/res/res/values-mcc310-mnc950-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-et/strings.xml b/core/res/res/values-mcc310-mnc950-et/strings.xml
index 013243a..14b4d45 100644
--- a/core/res/res/values-mcc310-mnc950-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-eu/strings.xml b/core/res/res/values-mcc310-mnc950-eu/strings.xml
index 097e423..2e33d02 100644
--- a/core/res/res/values-mcc310-mnc950-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-fa/strings.xml b/core/res/res/values-mcc310-mnc950-fa/strings.xml
index 3281bb5..f889d5e 100644
--- a/core/res/res/values-mcc310-mnc950-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-fi/strings.xml b/core/res/res/values-mcc310-mnc950-fi/strings.xml
index 01e04f7..846ee78 100644
--- a/core/res/res/values-mcc310-mnc950-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml
index a310f82..08a3e55 100644
--- a/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-fr/strings.xml b/core/res/res/values-mcc310-mnc950-fr/strings.xml
index 7b0fb2c..a0f6016 100644
--- a/core/res/res/values-mcc310-mnc950-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-gl/strings.xml b/core/res/res/values-mcc310-mnc950-gl/strings.xml
index 55ff461..e771683 100644
--- a/core/res/res/values-mcc310-mnc950-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-gu/strings.xml b/core/res/res/values-mcc310-mnc950-gu/strings.xml
index a6e1a83..d798a42 100644
--- a/core/res/res/values-mcc310-mnc950-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-gu/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-hi/strings.xml b/core/res/res/values-mcc310-mnc950-hi/strings.xml
index 41b9bc9..f107cb8 100644
--- a/core/res/res/values-mcc310-mnc950-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-hi/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM की अनुमति नहीं है MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-hr/strings.xml b/core/res/res/values-mcc310-mnc950-hr/strings.xml
index 1c39a09..c7f6b22 100644
--- a/core/res/res/values-mcc310-mnc950-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-hu/strings.xml b/core/res/res/values-mcc310-mnc950-hu/strings.xml
index 6b8ee76..22b5e9b 100644
--- a/core/res/res/values-mcc310-mnc950-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-hy/strings.xml b/core/res/res/values-mcc310-mnc950-hy/strings.xml
index 63dfa46..5136640 100644
--- a/core/res/res/values-mcc310-mnc950-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-in/strings.xml b/core/res/res/values-mcc310-mnc950-in/strings.xml
index a7c0232..bb9e380 100644
--- a/core/res/res/values-mcc310-mnc950-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-is/strings.xml b/core/res/res/values-mcc310-mnc950-is/strings.xml
index ceee15a..d8b847f 100644
--- a/core/res/res/values-mcc310-mnc950-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-it/strings.xml b/core/res/res/values-mcc310-mnc950-it/strings.xml
index 21e2a4a..bf6d8bb 100644
--- a/core/res/res/values-mcc310-mnc950-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-iw/strings.xml b/core/res/res/values-mcc310-mnc950-iw/strings.xml
index 041408f..aab4f00 100644
--- a/core/res/res/values-mcc310-mnc950-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-iw/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ja/strings.xml b/core/res/res/values-mcc310-mnc950-ja/strings.xml
index 97f697e..4224a8a 100644
--- a/core/res/res/values-mcc310-mnc950-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ka/strings.xml b/core/res/res/values-mcc310-mnc950-ka/strings.xml
index 4d8c8a8..0cbd72c 100644
--- a/core/res/res/values-mcc310-mnc950-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-kk/strings.xml b/core/res/res/values-mcc310-mnc950-kk/strings.xml
index 899a9a2..271083a 100644
--- a/core/res/res/values-mcc310-mnc950-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-km/strings.xml b/core/res/res/values-mcc310-mnc950-km/strings.xml
index 3c80d9f..d5a98d5 100644
--- a/core/res/res/values-mcc310-mnc950-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-kn/strings.xml b/core/res/res/values-mcc310-mnc950-kn/strings.xml
index 1c7ab20..fac211a 100644
--- a/core/res/res/values-mcc310-mnc950-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-kn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ko/strings.xml b/core/res/res/values-mcc310-mnc950-ko/strings.xml
index 2419c2a..96c9b62 100644
--- a/core/res/res/values-mcc310-mnc950-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ky/strings.xml b/core/res/res/values-mcc310-mnc950-ky/strings.xml
index 2583338..f8c7313 100644
--- a/core/res/res/values-mcc310-mnc950-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ky/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM карта таанылган жок (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-lo/strings.xml b/core/res/res/values-mcc310-mnc950-lo/strings.xml
index b69536f..38f82b4 100644
--- a/core/res/res/values-mcc310-mnc950-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-lt/strings.xml b/core/res/res/values-mcc310-mnc950-lt/strings.xml
index 8ef0869..4c51da7 100644
--- a/core/res/res/values-mcc310-mnc950-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-lv/strings.xml b/core/res/res/values-mcc310-mnc950-lv/strings.xml
index 2a491c0..0ed0ae7 100644
--- a/core/res/res/values-mcc310-mnc950-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-mk/strings.xml b/core/res/res/values-mcc310-mnc950-mk/strings.xml
index a1da44b..375b09a 100644
--- a/core/res/res/values-mcc310-mnc950-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ml/strings.xml b/core/res/res/values-mcc310-mnc950-ml/strings.xml
index 0079c08..68dff8d 100644
--- a/core/res/res/values-mcc310-mnc950-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ml/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-mn/strings.xml b/core/res/res/values-mcc310-mnc950-mn/strings.xml
index 2d4b5f5..e8ef11c 100644
--- a/core/res/res/values-mcc310-mnc950-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-mr/strings.xml b/core/res/res/values-mcc310-mnc950-mr/strings.xml
index eca7dca..cd6d9dd 100644
--- a/core/res/res/values-mcc310-mnc950-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-mr/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ms/strings.xml b/core/res/res/values-mcc310-mnc950-ms/strings.xml
index 4f5c781..bb4600d 100644
--- a/core/res/res/values-mcc310-mnc950-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-my/strings.xml b/core/res/res/values-mcc310-mnc950-my/strings.xml
index ecf9f61..ed581ef 100644
--- a/core/res/res/values-mcc310-mnc950-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-nb/strings.xml b/core/res/res/values-mcc310-mnc950-nb/strings.xml
index 907482e..5134e7d 100644
--- a/core/res/res/values-mcc310-mnc950-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ne/strings.xml b/core/res/res/values-mcc310-mnc950-ne/strings.xml
index 380f01c..3d41dfd 100644
--- a/core/res/res/values-mcc310-mnc950-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ne/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM लाई अनुमति छैन MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-nl/strings.xml b/core/res/res/values-mcc310-mnc950-nl/strings.xml
index a01896c..d1e39df 100644
--- a/core/res/res/values-mcc310-mnc950-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-pa/strings.xml b/core/res/res/values-mcc310-mnc950-pa/strings.xml
index a67b0fb..a0f1fbc 100644
--- a/core/res/res/values-mcc310-mnc950-pa/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-pa/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-pl/strings.xml b/core/res/res/values-mcc310-mnc950-pl/strings.xml
index ce40c22..ab6e8fb 100644
--- a/core/res/res/values-mcc310-mnc950-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml
index 1f89e47..83c84ce 100644
--- a/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml
index 1f89e47..7b657fd 100644
--- a/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-pt/strings.xml b/core/res/res/values-mcc310-mnc950-pt/strings.xml
index 1f89e47..83c84ce 100644
--- a/core/res/res/values-mcc310-mnc950-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ro/strings.xml b/core/res/res/values-mcc310-mnc950-ro/strings.xml
index 7fb3f2e..e51800b 100644
--- a/core/res/res/values-mcc310-mnc950-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ru/strings.xml b/core/res/res/values-mcc310-mnc950-ru/strings.xml
index 16deeed..1dbdd7b 100644
--- a/core/res/res/values-mcc310-mnc950-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-si/strings.xml b/core/res/res/values-mcc310-mnc950-si/strings.xml
index dd512d9..bb0f22f 100644
--- a/core/res/res/values-mcc310-mnc950-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sk/strings.xml b/core/res/res/values-mcc310-mnc950-sk/strings.xml
index 6a8e6f0..7bba3ae 100644
--- a/core/res/res/values-mcc310-mnc950-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sl/strings.xml b/core/res/res/values-mcc310-mnc950-sl/strings.xml
index 391ee78..cd08650 100644
--- a/core/res/res/values-mcc310-mnc950-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sq/strings.xml b/core/res/res/values-mcc310-mnc950-sq/strings.xml
index ebc978c..8230755 100644
--- a/core/res/res/values-mcc310-mnc950-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sr/strings.xml b/core/res/res/values-mcc310-mnc950-sr/strings.xml
index 4f3f86f..cac39e2 100644
--- a/core/res/res/values-mcc310-mnc950-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sv/strings.xml b/core/res/res/values-mcc310-mnc950-sv/strings.xml
index 4739f06..7ac957d 100644
--- a/core/res/res/values-mcc310-mnc950-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sw/strings.xml b/core/res/res/values-mcc310-mnc950-sw/strings.xml
index 903b4a5..8967e18 100644
--- a/core/res/res/values-mcc310-mnc950-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ta/strings.xml b/core/res/res/values-mcc310-mnc950-ta/strings.xml
index 8838aed..15f182b 100644
--- a/core/res/res/values-mcc310-mnc950-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ta/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-te/strings.xml b/core/res/res/values-mcc310-mnc950-te/strings.xml
index dc9625b..4611a72 100644
--- a/core/res/res/values-mcc310-mnc950-te/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-te/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM MM#2ని సక్రియం చేయలేదు"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ఫోన్ అనుమతించబడదు MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-th/strings.xml b/core/res/res/values-mcc310-mnc950-th/strings.xml
index 3feb1f6..d8c61dd 100644
--- a/core/res/res/values-mcc310-mnc950-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-tl/strings.xml b/core/res/res/values-mcc310-mnc950-tl/strings.xml
index 55e0bfd..66f686c 100644
--- a/core/res/res/values-mcc310-mnc950-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-tr/strings.xml b/core/res/res/values-mcc310-mnc950-tr/strings.xml
index 7a274a4..54e8e7d 100644
--- a/core/res/res/values-mcc310-mnc950-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-uk/strings.xml b/core/res/res/values-mcc310-mnc950-uk/strings.xml
index bf5e6411..be0cd2b 100644
--- a/core/res/res/values-mcc310-mnc950-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ur/strings.xml b/core/res/res/values-mcc310-mnc950-ur/strings.xml
index 35857cd..32174a5 100644
--- a/core/res/res/values-mcc310-mnc950-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ur/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (8920048244573695129) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-uz/strings.xml b/core/res/res/values-mcc310-mnc950-uz/strings.xml
index e31c7b6..99ac738 100644
--- a/core/res/res/values-mcc310-mnc950-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-vi/strings.xml b/core/res/res/values-mcc310-mnc950-vi/strings.xml
index b9360b5..829a4dc 100644
--- a/core/res/res/values-mcc310-mnc950-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml
index 3b4ba0a..240dd0b 100644
--- a/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml
index 763e498..97a13bc 100644
--- a/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml
index 763e498..934aea0 100644
--- a/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-zu/strings.xml b/core/res/res/values-mcc310-mnc950-zu/strings.xml
index 1c29754..9dc4403 100644
--- a/core/res/res/values-mcc310-mnc950-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950/strings.xml b/core/res/res/values-mcc310-mnc950/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc950/strings.xml
+++ b/core/res/res/values-mcc310-mnc950/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-af/strings.xml b/core/res/res/values-mcc311-mnc180-af/strings.xml
index ead8992..73c9a6c 100644
--- a/core/res/res/values-mcc311-mnc180-af/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-am/strings.xml b/core/res/res/values-mcc311-mnc180-am/strings.xml
index a7d0d1d..935312e 100644
--- a/core/res/res/values-mcc311-mnc180-am/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ar/strings.xml b/core/res/res/values-mcc311-mnc180-ar/strings.xml
index f5412bd..cdb14c5 100644
--- a/core/res/res/values-mcc311-mnc180-ar/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-az/strings.xml b/core/res/res/values-mcc311-mnc180-az/strings.xml
index c2c06be..7471fca 100644
--- a/core/res/res/values-mcc311-mnc180-az/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml b/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml
index e8b35c3..2d0af9e 100644
--- a/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM kartica nije podešena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-be/strings.xml b/core/res/res/values-mcc311-mnc180-be/strings.xml
index f2c1069..0b2f7cf 100644
--- a/core/res/res/values-mcc311-mnc180-be/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-be/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-карты няма MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-карта не дапускаецца MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Тэлефон не дапускаецца MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-bg/strings.xml b/core/res/res/values-mcc311-mnc180-bg/strings.xml
index faf5a42..542557e 100644
--- a/core/res/res/values-mcc311-mnc180-bg/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-bn/strings.xml b/core/res/res/values-mcc311-mnc180-bn/strings.xml
index 80efd0f..3f42706 100644
--- a/core/res/res/values-mcc311-mnc180-bn/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-bn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"সিমের অনুমতি নেই MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-bs/strings.xml b/core/res/res/values-mcc311-mnc180-bs/strings.xml
index 7c3e5b3..409df22 100644
--- a/core/res/res/values-mcc311-mnc180-bs/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-bs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM kartica nije dodijeljena MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ca/strings.xml b/core/res/res/values-mcc311-mnc180-ca/strings.xml
index e33a901..505f396 100644
--- a/core/res/res/values-mcc311-mnc180-ca/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-cs/strings.xml b/core/res/res/values-mcc311-mnc180-cs/strings.xml
index 653a55a..29c8fdf 100644
--- a/core/res/res/values-mcc311-mnc180-cs/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-da/strings.xml b/core/res/res/values-mcc311-mnc180-da/strings.xml
index 04c89a5..6fadac1 100644
--- a/core/res/res/values-mcc311-mnc180-da/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-de/strings.xml b/core/res/res/values-mcc311-mnc180-de/strings.xml
index 8fef081..714eac9 100644
--- a/core/res/res/values-mcc311-mnc180-de/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-el/strings.xml b/core/res/res/values-mcc311-mnc180-el/strings.xml
index 795f48f..2e29b12 100644
--- a/core/res/res/values-mcc311-mnc180-el/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml b/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml
index 9c972bc..b284371 100644
--- a/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rCA/strings.xml b/core/res/res/values-mcc311-mnc180-en-rCA/strings.xml
index 9c972bc..b284371 100644
--- a/core/res/res/values-mcc311-mnc180-en-rCA/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-en-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml b/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml
index 9c972bc..b284371 100644
--- a/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml b/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml
index 9c972bc..b284371 100644
--- a/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rXC/strings.xml b/core/res/res/values-mcc311-mnc180-en-rXC/strings.xml
index f1a6cc7..53832df 100644
--- a/core/res/res/values-mcc311-mnc180-en-rXC/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-en-rXC/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‎‎SIM not provisioned MM#2‎‏‎‎‏‎"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎SIM not allowed MM#3‎‏‎‎‏‎"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml b/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml
index 694cd76..cb06a6e 100644
--- a/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-es/strings.xml b/core/res/res/values-mcc311-mnc180-es/strings.xml
index 605e314..6368483 100644
--- a/core/res/res/values-mcc311-mnc180-es/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-et/strings.xml b/core/res/res/values-mcc311-mnc180-et/strings.xml
index 39dfa1b..142824f 100644
--- a/core/res/res/values-mcc311-mnc180-et/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-eu/strings.xml b/core/res/res/values-mcc311-mnc180-eu/strings.xml
index 84732c9..4bb3cd3 100644
--- a/core/res/res/values-mcc311-mnc180-eu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-fa/strings.xml b/core/res/res/values-mcc311-mnc180-fa/strings.xml
index 902d821..3354859 100644
--- a/core/res/res/values-mcc311-mnc180-fa/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-fi/strings.xml b/core/res/res/values-mcc311-mnc180-fi/strings.xml
index 004e645..c66d593 100644
--- a/core/res/res/values-mcc311-mnc180-fi/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml b/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml
index c0aaf99..b17c342 100644
--- a/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-fr/strings.xml b/core/res/res/values-mcc311-mnc180-fr/strings.xml
index b9adf79..0cc7264 100644
--- a/core/res/res/values-mcc311-mnc180-fr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-gl/strings.xml b/core/res/res/values-mcc311-mnc180-gl/strings.xml
index cb59c97..8acb5c1 100644
--- a/core/res/res/values-mcc311-mnc180-gl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-gu/strings.xml b/core/res/res/values-mcc311-mnc180-gu/strings.xml
index 556416e..7931f3e 100644
--- a/core/res/res/values-mcc311-mnc180-gu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-gu/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-hi/strings.xml b/core/res/res/values-mcc311-mnc180-hi/strings.xml
index da1f9e1..9ac161d 100644
--- a/core/res/res/values-mcc311-mnc180-hi/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-hi/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM की अनुमति नहीं है MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-hr/strings.xml b/core/res/res/values-mcc311-mnc180-hr/strings.xml
index a1f0b0e..84d36b7 100644
--- a/core/res/res/values-mcc311-mnc180-hr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-hu/strings.xml b/core/res/res/values-mcc311-mnc180-hu/strings.xml
index 917c2ee9..5d3507d 100644
--- a/core/res/res/values-mcc311-mnc180-hu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-hy/strings.xml b/core/res/res/values-mcc311-mnc180-hy/strings.xml
index a832d02..aeaaeb9 100644
--- a/core/res/res/values-mcc311-mnc180-hy/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-in/strings.xml b/core/res/res/values-mcc311-mnc180-in/strings.xml
index bdc8d20..8a96e4c 100644
--- a/core/res/res/values-mcc311-mnc180-in/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-is/strings.xml b/core/res/res/values-mcc311-mnc180-is/strings.xml
index 35966f7..bd6223b 100644
--- a/core/res/res/values-mcc311-mnc180-is/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-it/strings.xml b/core/res/res/values-mcc311-mnc180-it/strings.xml
index 25f301b..7757a25 100644
--- a/core/res/res/values-mcc311-mnc180-it/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-iw/strings.xml b/core/res/res/values-mcc311-mnc180-iw/strings.xml
index c6bdc14..10db607 100644
--- a/core/res/res/values-mcc311-mnc180-iw/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-iw/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ja/strings.xml b/core/res/res/values-mcc311-mnc180-ja/strings.xml
index 6d30808..3defd2e 100644
--- a/core/res/res/values-mcc311-mnc180-ja/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ka/strings.xml b/core/res/res/values-mcc311-mnc180-ka/strings.xml
index b86ce07..2fa76c4 100644
--- a/core/res/res/values-mcc311-mnc180-ka/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-kk/strings.xml b/core/res/res/values-mcc311-mnc180-kk/strings.xml
index 539fbe4..91fd767 100644
--- a/core/res/res/values-mcc311-mnc180-kk/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-km/strings.xml b/core/res/res/values-mcc311-mnc180-km/strings.xml
index 970532e..c2f29a5 100644
--- a/core/res/res/values-mcc311-mnc180-km/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-kn/strings.xml b/core/res/res/values-mcc311-mnc180-kn/strings.xml
index 53a0419..980f49e0 100644
--- a/core/res/res/values-mcc311-mnc180-kn/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-kn/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ko/strings.xml b/core/res/res/values-mcc311-mnc180-ko/strings.xml
index 01d6fec..b9bd3c8 100644
--- a/core/res/res/values-mcc311-mnc180-ko/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ky/strings.xml b/core/res/res/values-mcc311-mnc180-ky/strings.xml
index 7339e40..305d81e 100644
--- a/core/res/res/values-mcc311-mnc180-ky/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ky/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM карта таанылган жок (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-lo/strings.xml b/core/res/res/values-mcc311-mnc180-lo/strings.xml
index 5cbd1c8..f662b44 100644
--- a/core/res/res/values-mcc311-mnc180-lo/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-lt/strings.xml b/core/res/res/values-mcc311-mnc180-lt/strings.xml
index 40a7e4a..fbffbae 100644
--- a/core/res/res/values-mcc311-mnc180-lt/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-lv/strings.xml b/core/res/res/values-mcc311-mnc180-lv/strings.xml
index 74b6818..747b5ea 100644
--- a/core/res/res/values-mcc311-mnc180-lv/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-mk/strings.xml b/core/res/res/values-mcc311-mnc180-mk/strings.xml
index 7db80fa..9077dc2 100644
--- a/core/res/res/values-mcc311-mnc180-mk/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ml/strings.xml b/core/res/res/values-mcc311-mnc180-ml/strings.xml
index 7cdd126..fece3ea 100644
--- a/core/res/res/values-mcc311-mnc180-ml/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ml/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-mn/strings.xml b/core/res/res/values-mcc311-mnc180-mn/strings.xml
index 1be055c..4960154 100644
--- a/core/res/res/values-mcc311-mnc180-mn/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-mr/strings.xml b/core/res/res/values-mcc311-mnc180-mr/strings.xml
index f8e08ae..bc58871 100644
--- a/core/res/res/values-mcc311-mnc180-mr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-mr/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ms/strings.xml b/core/res/res/values-mcc311-mnc180-ms/strings.xml
index 305a10d..222d346 100644
--- a/core/res/res/values-mcc311-mnc180-ms/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-my/strings.xml b/core/res/res/values-mcc311-mnc180-my/strings.xml
index 306c0dd..d68c8ba 100644
--- a/core/res/res/values-mcc311-mnc180-my/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-nb/strings.xml b/core/res/res/values-mcc311-mnc180-nb/strings.xml
index e1296f4..d2c4758 100644
--- a/core/res/res/values-mcc311-mnc180-nb/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ne/strings.xml b/core/res/res/values-mcc311-mnc180-ne/strings.xml
index 6177a83..1ef6082 100644
--- a/core/res/res/values-mcc311-mnc180-ne/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ne/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM लाई अनुमति छैन MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-nl/strings.xml b/core/res/res/values-mcc311-mnc180-nl/strings.xml
index 3f12e64..fbfd787 100644
--- a/core/res/res/values-mcc311-mnc180-nl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-pa/strings.xml b/core/res/res/values-mcc311-mnc180-pa/strings.xml
index 32f6a7e..8ec8bdf 100644
--- a/core/res/res/values-mcc311-mnc180-pa/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-pa/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-pl/strings.xml b/core/res/res/values-mcc311-mnc180-pl/strings.xml
index 0744491..296000e 100644
--- a/core/res/res/values-mcc311-mnc180-pl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml b/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml
index c4d2240..637a91c 100644
--- a/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml b/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml
index c4d2240..7938a5f 100644
--- a/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-pt/strings.xml b/core/res/res/values-mcc311-mnc180-pt/strings.xml
index c4d2240..637a91c 100644
--- a/core/res/res/values-mcc311-mnc180-pt/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ro/strings.xml b/core/res/res/values-mcc311-mnc180-ro/strings.xml
index 68cab29..c5126e7 100644
--- a/core/res/res/values-mcc311-mnc180-ro/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ru/strings.xml b/core/res/res/values-mcc311-mnc180-ru/strings.xml
index 90a3a09..a6f6785 100644
--- a/core/res/res/values-mcc311-mnc180-ru/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-si/strings.xml b/core/res/res/values-mcc311-mnc180-si/strings.xml
index 1907d3e..b9ef425 100644
--- a/core/res/res/values-mcc311-mnc180-si/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sk/strings.xml b/core/res/res/values-mcc311-mnc180-sk/strings.xml
index a456431..ecd9222 100644
--- a/core/res/res/values-mcc311-mnc180-sk/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sl/strings.xml b/core/res/res/values-mcc311-mnc180-sl/strings.xml
index 454a1cd..33d9621 100644
--- a/core/res/res/values-mcc311-mnc180-sl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sq/strings.xml b/core/res/res/values-mcc311-mnc180-sq/strings.xml
index 23da1a3..b5b28fa 100644
--- a/core/res/res/values-mcc311-mnc180-sq/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sr/strings.xml b/core/res/res/values-mcc311-mnc180-sr/strings.xml
index 182a7bc..e8b6017 100644
--- a/core/res/res/values-mcc311-mnc180-sr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sv/strings.xml b/core/res/res/values-mcc311-mnc180-sv/strings.xml
index fee7a1f..9ca48e0 100644
--- a/core/res/res/values-mcc311-mnc180-sv/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sw/strings.xml b/core/res/res/values-mcc311-mnc180-sw/strings.xml
index e49b3d1..5b76485 100644
--- a/core/res/res/values-mcc311-mnc180-sw/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ta/strings.xml b/core/res/res/values-mcc311-mnc180-ta/strings.xml
index 6c11c4f..62abe5c 100644
--- a/core/res/res/values-mcc311-mnc180-ta/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ta/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-te/strings.xml b/core/res/res/values-mcc311-mnc180-te/strings.xml
index 5bb9f97..90fe4ca 100644
--- a/core/res/res/values-mcc311-mnc180-te/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-te/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM MM#2ని సక్రియం చేయలేదు"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ఫోన్ అనుమతించబడదు MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-th/strings.xml b/core/res/res/values-mcc311-mnc180-th/strings.xml
index be4b08e..d587bcd 100644
--- a/core/res/res/values-mcc311-mnc180-th/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-tl/strings.xml b/core/res/res/values-mcc311-mnc180-tl/strings.xml
index 6aacf16..963db42 100644
--- a/core/res/res/values-mcc311-mnc180-tl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-tr/strings.xml b/core/res/res/values-mcc311-mnc180-tr/strings.xml
index cf4fd77..28280f0 100644
--- a/core/res/res/values-mcc311-mnc180-tr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-uk/strings.xml b/core/res/res/values-mcc311-mnc180-uk/strings.xml
index fae40ac..00b22d9 100644
--- a/core/res/res/values-mcc311-mnc180-uk/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ur/strings.xml b/core/res/res/values-mcc311-mnc180-ur/strings.xml
index ebceb5e..b2d03ac 100644
--- a/core/res/res/values-mcc311-mnc180-ur/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ur/strings.xml
@@ -22,4 +22,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <!-- no translation found for mmcc_illegal_me (5766888847785331904) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-uz/strings.xml b/core/res/res/values-mcc311-mnc180-uz/strings.xml
index ebcdd3b..c6f9b37 100644
--- a/core/res/res/values-mcc311-mnc180-uz/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-vi/strings.xml b/core/res/res/values-mcc311-mnc180-vi/strings.xml
index 0d7ff96..b5a6567 100644
--- a/core/res/res/values-mcc311-mnc180-vi/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml b/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml
index d8ff182..cd27edf 100644
--- a/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml b/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml
index 14332bf..9f2f8b9 100644
--- a/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM 卡不允許 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml b/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml
index 775a70b..9336296 100644
--- a/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-zu/strings.xml b/core/res/res/values-mcc311-mnc180-zu/strings.xml
index a66760f..5708a22 100644
--- a/core/res/res/values-mcc311-mnc180-zu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180/strings.xml b/core/res/res/values-mcc311-mnc180/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc311-mnc180/strings.xml
+++ b/core/res/res/values-mcc311-mnc180/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-af/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-af/strings.xml
index fc20be6..8884326 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-af/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Foon nie toegelaat nie MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-am/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-am/strings.xml
index fc20be6..26c082b 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-am/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"ስልክ አይፈቀድም MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-ar/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-ar/strings.xml
index fc20be6..133e2b0 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-ar/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"‏غير مسموح باستخدام الهاتف MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-az/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-az/strings.xml
index fc20be6..80a1926 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-az/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"MM#6 telefonu dəstəklənmir"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml
index fc20be6..47b219e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefon nije dozvoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-be/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-be/strings.xml
index fc20be6..ad5d190 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-be/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Тэлефон не дапускаецца MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-bg/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-bg/strings.xml
index fc20be6..98a60c5 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-bg/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Телефонът не е разрешен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-bs/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-bs/strings.xml
index fc20be6..47b219e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-bs/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefon nije dozvoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-ca/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-ca/strings.xml
index fc20be6..adaa2ba 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-ca/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telèfon no compatible MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-cs/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-cs/strings.xml
index fc20be6..b88b619 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-cs/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefon není povolen (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-da/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-da/strings.xml
index fc20be6..50fdbd4 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-da/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefonen har ikke adgangstilladelse MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-de/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-de/strings.xml
index fc20be6..18b33e5 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-de/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Smartphone nicht zulässig MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-el/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-el/strings.xml
index fc20be6..22ea1db 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-el/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-en-rAU/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-en-rAU/strings.xml
index fc20be6..3eb880a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-en-rAU/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-en-rCA/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-en-rCA/strings.xml
index fc20be6..3eb880a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-en-rCA/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-en-rGB/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-en-rGB/strings.xml
index fc20be6..3eb880a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-en-rGB/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-en-rIN/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-en-rIN/strings.xml
index fc20be6..3eb880a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-en-rIN/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-en-rXC/strings.xml b/core/res/res/values-mcc312-mnc670-en-rXC/strings.xml
new file mode 100644
index 0000000..be68f41
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-en-rXC/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-es-rUS/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-es-rUS/strings.xml
index fc20be6..89b28f5 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-es-rUS/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-es/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-es/strings.xml
index fc20be6..89b28f5 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-es/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-et/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-et/strings.xml
index fc20be6..1ed4b41 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-et/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefon pole lubatud MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-eu/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-eu/strings.xml
index fc20be6..8f0daba 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-eu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefonoa ez da onartzen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc312-mnc670-fa/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc312-mnc670-fa/strings.xml
index e998b9a..bd87bdf 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-fa/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc312-mnc670-fi/strings.xml
similarity index 66%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc312-mnc670-fi/strings.xml
index e998b9a..5ec33a3 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-fi/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-fr-rCA/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-fr-rCA/strings.xml
index fc20be6..2110dda 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-fr-rCA/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-fr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-fr/strings.xml
index fc20be6..2110dda 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-fr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-gl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-gl/strings.xml
index fc20be6..dc66c1d 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-gl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Non se admite o teléfono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-hr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-hr/strings.xml
index fc20be6..e3b49c9 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-hr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefon nije dopušten MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc312-mnc670-hu/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc312-mnc670-hu/strings.xml
index e998b9a..85b947c 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-hu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-hy/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-hy/strings.xml
index fc20be6..bc39d50 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-hy/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-in/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-in/strings.xml
index fc20be6..0f526dd 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-in/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Ponsel tidak diizinkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-is/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-is/strings.xml
index fc20be6..cad2282 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-is/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Sími ekki leyfður MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-it/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-it/strings.xml
index fc20be6..1763bdc 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-it/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefono non consentito MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-ja/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-ja/strings.xml
index fc20be6..c5de3af 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-ja/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"電話は許可されていません(MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-ka/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-ka/strings.xml
index fc20be6..a2c7b8a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-ka/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"ტელეფონი დაუშვებელია MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-kk/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-kk/strings.xml
index fc20be6..1ac2314 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-kk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Телефон пайдалануға болмайды MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-km/strings.xml
similarity index 61%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-km/strings.xml
index fc20be6..8786411 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-km/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc312-mnc670-ko/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc312-mnc670-ko/strings.xml
index e998b9a..fcd98f9 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-ko/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-ky/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-ky/strings.xml
index fc20be6..ed830f6 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-ky/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Телефонду колдонууга тыюу салынган MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-lo/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-lo/strings.xml
index fc20be6..04bb1c9 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-lo/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-lt/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-lt/strings.xml
index fc20be6..c416a9a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-lt/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefonas neleidžiamas (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-lv/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-lv/strings.xml
index fc20be6..dfed609 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-lv/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Tālruni nav atļauts izmantot: MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-mk/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-mk/strings.xml
index fc20be6..0bf51cc 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-mk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Телефонот не е дозволен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-mn/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-mn/strings.xml
index fc20be6..682cf86 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-mn/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Утсыг зөвшөөрөөгүй MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-ms/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-ms/strings.xml
index fc20be6..3e807a0 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-ms/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefon tidak dibenarkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-my/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-my/strings.xml
index fc20be6..292e8db 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-my/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-nb/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-nb/strings.xml
index fc20be6..431fda6 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-nb/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefonen er ikke tillatt, MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-nl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-nl/strings.xml
index fc20be6..d7eb032 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-nl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefoon niet toegestaan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-pl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-pl/strings.xml
index fc20be6..dd39c79 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-pl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"MM#6 – telefon niedozwolony"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-pt-rBR/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-pt-rBR/strings.xml
index fc20be6..bb58d18 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-pt-rBR/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-pt-rPT/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-pt-rPT/strings.xml
index fc20be6..f04d740 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-pt-rPT/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telemóvel não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-pt/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-pt/strings.xml
index fc20be6..bb58d18 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-pt/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-ro/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-ro/strings.xml
index fc20be6..3129943 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-ro/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefonul nu este permis MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-ru/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-ru/strings.xml
index fc20be6..46080e0 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-ru/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Звонки запрещены (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-si/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-si/strings.xml
index fc20be6..6fdac6b 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-si/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-sk/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-sk/strings.xml
index fc20be6..c717019 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-sk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefón nie je povolený (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-sl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-sl/strings.xml
index fc20be6..15c7670 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-sl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefon ni dovoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-sq/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-sq/strings.xml
index fc20be6..5c97026 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-sq/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefoni nuk lejohet MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-sr/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-sr/strings.xml
index fc20be6..9fdf70d 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-sr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Телефон није дозвољен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-sv/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-sv/strings.xml
index fc20be6..0f9d454 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-sv/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Mobil tillåts inte MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-sw/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-sw/strings.xml
index fc20be6..e2c461e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-sw/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Simu hairuhusiwi MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-te/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-te/strings.xml
index fc20be6..f9bd60a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-te/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-th/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-th/strings.xml
index fc20be6..b144ca3 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-th/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-tl/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-tl/strings.xml
index fc20be6..79b88ec 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-tl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Hindi pinapahintulutan ang telepono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-tr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-tr/strings.xml
index fc20be6..1e3dcea 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-tr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Telefona izin verilmiyor MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-uk/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-uk/strings.xml
index fc20be6..d2dd817 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-uk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Телефон заборонено (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-uz/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-uz/strings.xml
index fc20be6..4bf0f74 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-uz/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Chaqiruvlar taqiqlangan (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-vi/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-vi/strings.xml
index fc20be6..4bae4af 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-vi/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Không cho phép điện thoại MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-zh-rCN/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-zh-rCN/strings.xml
index fc20be6..317531a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-zh-rCN/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"不受允许的手机 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc312-mnc670-zh-rHK/strings.xml
similarity index 66%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc312-mnc670-zh-rHK/strings.xml
index e998b9a..bef6362 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-zh-rHK/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-zh-rTW/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-zh-rTW/strings.xml
index fc20be6..1fa82ed 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-zh-rTW/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"不支援的手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670-zu/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670-zu/strings.xml
index fc20be6..35c2cbf 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-zu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="3649306773478362802">"Ifoni ayivunyelwe MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc312-mnc670/strings.xml
similarity index 78%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc312-mnc670/strings.xml
index fc20be6..96af975 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc312-mnc670/strings.xml
@@ -2,7 +2,7 @@
 <!--
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -18,8 +18,5 @@
 */
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-af/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-af/strings.xml
index fc20be6..7645fc8 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-af/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Foon nie toegelaat nie MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-am/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-am/strings.xml
index fc20be6..b76ed04 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-am/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"ስልክ አይፈቀድም MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-ar/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-ar/strings.xml
index fc20be6..640fb8a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-ar/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"‏غير مسموح باستخدام الهاتف MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-az/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-az/strings.xml
index fc20be6..44796df 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-az/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"MM#6 telefonu dəstəklənmir"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml
index fc20be6..d5bf39e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefon nije dozvoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-be/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-be/strings.xml
index fc20be6..c9f4633 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-be/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Тэлефон не дапускаецца MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-bg/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-bg/strings.xml
index fc20be6..8c946ed 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-bg/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Телефонът не е разрешен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-bs/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-bs/strings.xml
index fc20be6..d5bf39e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-bs/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefon nije dozvoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-ca/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-ca/strings.xml
index fc20be6..f6846cb 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-ca/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telèfon no compatible MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-cs/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-cs/strings.xml
index fc20be6..4e57d15 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-cs/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefon není povolen (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-da/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-da/strings.xml
index fc20be6..c00d95c 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-da/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefonen har ikke adgangstilladelse MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-de/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-de/strings.xml
index fc20be6..df08b13 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-de/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Smartphone nicht zulässig MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-el/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-el/strings.xml
index fc20be6..0fcb42e 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-el/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-en-rAU/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-en-rAU/strings.xml
index fc20be6..f1a3611 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-en-rAU/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-en-rCA/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-en-rCA/strings.xml
index fc20be6..f1a3611 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-en-rCA/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-en-rGB/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-en-rGB/strings.xml
index fc20be6..f1a3611 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-en-rGB/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-en-rIN/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-en-rIN/strings.xml
index fc20be6..f1a3611 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-en-rIN/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-en-rXC/strings.xml b/core/res/res/values-mcc313-mnc100-en-rXC/strings.xml
new file mode 100644
index 0000000..8a8bf7e
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-en-rXC/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‎‎Phone not allowed MM#6‎‏‎‎‏‎"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-es-rUS/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-es-rUS/strings.xml
index fc20be6..122d4b9 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-es-rUS/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-es/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-es/strings.xml
index fc20be6..122d4b9 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-es/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-et/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-et/strings.xml
index fc20be6..83cfbaf 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-et/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefon pole lubatud MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-eu/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-eu/strings.xml
index fc20be6..028ca37 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-eu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefonoa ez da onartzen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc313-mnc100-fa/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc313-mnc100-fa/strings.xml
index e998b9a..f29da6b 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-fa/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc313-mnc100-fi/strings.xml
similarity index 66%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc313-mnc100-fi/strings.xml
index e998b9a..f64a38a 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-fi/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-fr-rCA/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-fr-rCA/strings.xml
index fc20be6..89c50ea 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-fr-rCA/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-fr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-fr/strings.xml
index fc20be6..89c50ea 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-fr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-gl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-gl/strings.xml
index fc20be6..04390a0 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-gl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Non se admite o teléfono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-hr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-hr/strings.xml
index fc20be6..290e92b 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-hr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefon nije dopušten MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc313-mnc100-hu/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc313-mnc100-hu/strings.xml
index e998b9a..31605dd 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-hu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-hy/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-hy/strings.xml
index fc20be6..62acde3 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-hy/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-in/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-in/strings.xml
index fc20be6..d95657f 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-in/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Ponsel tidak diizinkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-is/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-is/strings.xml
index fc20be6..3ad7b3c 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-is/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Sími ekki leyfður MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-it/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-it/strings.xml
index fc20be6..1d3deeb 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-it/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefono non consentito MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-ja/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-ja/strings.xml
index fc20be6..6a89e3d 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-ja/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"電話は許可されていません(MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-ka/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-ka/strings.xml
index fc20be6..a063fc4 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-ka/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"ტელეფონი დაუშვებელია MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-kk/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-kk/strings.xml
index fc20be6..0562a2f 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-kk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Телефон пайдалануға болмайды MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-km/strings.xml
similarity index 61%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-km/strings.xml
index fc20be6..74e607b 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-km/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc313-mnc100-ko/strings.xml
similarity index 65%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc313-mnc100-ko/strings.xml
index e998b9a..fbe222b 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-ko/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-ky/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-ky/strings.xml
index fc20be6..8c08c4f 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-ky/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Телефонду колдонууга тыюу салынган MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-lo/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-lo/strings.xml
index fc20be6..793b87b 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-lo/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-lt/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-lt/strings.xml
index fc20be6..5edc6bf 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-lt/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefonas neleidžiamas (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-lv/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-lv/strings.xml
index fc20be6..de1ad9c 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-lv/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Tālruni nav atļauts izmantot: MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-mk/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-mk/strings.xml
index fc20be6..0b403e9 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-mk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Телефонот не е дозволен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-mn/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-mn/strings.xml
index fc20be6..5d5fbff 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-mn/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Утсыг зөвшөөрөөгүй MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-ms/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-ms/strings.xml
index fc20be6..ebd1724 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-ms/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefon tidak dibenarkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-my/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-my/strings.xml
index fc20be6..7de66f7 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-my/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-nb/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-nb/strings.xml
index fc20be6..84a7582 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-nb/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefonen er ikke tillatt, MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-nl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-nl/strings.xml
index fc20be6..14e940d 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-nl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefoon niet toegestaan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-pl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-pl/strings.xml
index fc20be6..7df915c 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-pl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"MM#6 – telefon niedozwolony"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-pt-rBR/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-pt-rBR/strings.xml
index fc20be6..f80f618 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-pt-rBR/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-pt-rPT/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-pt-rPT/strings.xml
index fc20be6..35d4f58 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-pt-rPT/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telemóvel não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-pt/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-pt/strings.xml
index fc20be6..f80f618 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-pt/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-ro/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-ro/strings.xml
index fc20be6..57a455d 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-ro/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefonul nu este permis MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-ru/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-ru/strings.xml
index fc20be6..8edec35 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-ru/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Звонки запрещены (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-si/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-si/strings.xml
index fc20be6..9493af0b 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-si/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-sk/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-sk/strings.xml
index fc20be6..04a1a08 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-sk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefón nie je povolený (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-sl/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-sl/strings.xml
index fc20be6..e59c833 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-sl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefon ni dovoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-sq/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-sq/strings.xml
index fc20be6..237a4a4 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-sq/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefoni nuk lejohet MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-sr/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-sr/strings.xml
index fc20be6..6d6c310 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-sr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Телефон није дозвољен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-sv/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-sv/strings.xml
index fc20be6..145a960 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-sv/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Mobil tillåts inte MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-sw/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-sw/strings.xml
index fc20be6..a7574fb 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-sw/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Simu hairuhusiwi MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-te/strings.xml
similarity index 63%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-te/strings.xml
index fc20be6..8908fb7 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-te/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-th/strings.xml
similarity index 62%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-th/strings.xml
index fc20be6..e562744 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-th/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-tl/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-tl/strings.xml
index fc20be6..6da1dbd 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-tl/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Hindi pinapahintulutan ang telepono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-tr/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-tr/strings.xml
index fc20be6..7200666 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-tr/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Telefona izin verilmiyor MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-uk/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-uk/strings.xml
index fc20be6..833f9b1 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-uk/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Телефон заборонено (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-uz/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-uz/strings.xml
index fc20be6..202a30c 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-uz/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Chaqiruvlar taqiqlangan (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-vi/strings.xml
similarity index 64%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-vi/strings.xml
index fc20be6..6a8c752 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-vi/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Không cho phép điện thoại MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-zh-rCN/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-zh-rCN/strings.xml
index fc20be6..056a75a 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-zh-rCN/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"不受允许的手机 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-large/strings.xml b/core/res/res/values-mcc313-mnc100-zh-rHK/strings.xml
similarity index 66%
copy from core/res/res/values-large/strings.xml
copy to core/res/res/values-mcc313-mnc100-zh-rHK/strings.xml
index e998b9a..db85730 100644
--- a/core/res/res/values-large/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-zh-rHK/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-zh-rTW/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-zh-rTW/strings.xml
index fc20be6..c907e39 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-zh-rTW/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"不支援的手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100-zu/strings.xml
similarity index 65%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100-zu/strings.xml
index fc20be6..1794f82 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-zu/strings.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -16,10 +16,9 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ -->
 
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me" msgid="7320955531336937252">"Ifoni ayivunyelwe MM#6"</string>
+</resources>
diff --git a/core/res/res/values-xlarge/strings.xml b/core/res/res/values-mcc313-mnc100/strings.xml
similarity index 78%
copy from core/res/res/values-xlarge/strings.xml
copy to core/res/res/values-mcc313-mnc100/strings.xml
index fc20be6..96af975 100644
--- a/core/res/res/values-xlarge/strings.xml
+++ b/core/res/res/values-mcc313-mnc100/strings.xml
@@ -2,7 +2,7 @@
 <!--
 /* //device/apps/common/assets/res/any/strings.xml
 **
-** Copyright 2010, The Android Open Source Project
+** Copyright 2006, 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.
@@ -18,8 +18,5 @@
 */
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false"></string>
-
-</resources>
\ No newline at end of file
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
+</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index a98e2f0..1ef32e1 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Предупредувања"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демонстрација за малопродажба"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-врска"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Апликацијата работи"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Апликации што ја трошат батеријата"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерија"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> апликации користат батерија"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Метод на внес"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дејства со текст"</string>
     <string name="email" msgid="4560673117055050403">"E-пошта"</string>
-    <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="6068210738233985748">"„Карти“"</string>
-    <string name="browse" msgid="6993590095938149861">"Прелистувач"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Контакт"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Меморијата е речиси полна"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некои системски функции може да не работат"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Нема доволно меморија во системот. Проверете дали има слободен простор од 250 МБ и рестартирајте."</string>
@@ -1791,4 +1797,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Не е дозволена SIM-картичка"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Не е дозволен телефон"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Појавен прозорец"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 65b7041..e4d586c 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"അഡ്‌മിൻ ആപ്പ് വിട്ടുപോയിരിക്കുന്നതിനാൽ ഔദ്യോഗിക പ്രൊഫൈൽ ഇല്ലാതാക്കി"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"ഔദ്യോഗിക പ്രൊഫൈൽ അഡ്‌മിൻ ആപ്പ് വിട്ടുപോയിരിക്കുന്നു അല്ലെങ്കിൽ കേടായിരിക്കുന്നു. ഫലമായി, നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലും ബന്ധപ്പെട്ട വിവരങ്ങളും ഇല്ലാതാക്കിയിരിക്കുന്നു. സഹായത്തിന് അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"ഈ ഉപകരണത്തിൽ തുടർന്നങ്ങോട്ട് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ ലഭ്യമല്ല"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"വളരെയധികം പാസ്‌വേഡ് ശ്രമങ്ങൾ"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ഉപകരണം മാനേജുചെയ്യുന്നുണ്ട്"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"നിങ്ങളുടെ സ്ഥാപനമാണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കുകയും ചെയ്തേക്കാം, വിശദാംശങ്ങൾ അറിയാൻ ടാപ്പുചെയ്യുക."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"നിങ്ങളുടെ ഉപകരണം മായ്‌ക്കും"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"അലേർട്ടുകൾ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"റീട്ടെയിൽ ഡെമോ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB കണക്ഷൻ"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ആപ്പുകൾ ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ആപ്പുകൾ ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ടൈപ്പുചെയ്യൽ രീതി"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ടെക്‌സ്‌റ്റ് പ്രവർത്തനങ്ങൾ"</string>
     <string name="email" msgid="4560673117055050403">"ഇമെയിൽ"</string>
-    <string name="dial" msgid="4204975095406423102">"ഫോണ്‍"</string>
-    <string name="map" msgid="6068210738233985748">"മാപ്‌സ്"</string>
-    <string name="browse" msgid="6993590095938149861">"ബ്രൗസർ"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"കോണ്‍‌ടാക്റ്റ്"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"സംഭരണയിടം കഴിഞ്ഞു"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ചില സിസ്റ്റം പ്രവർത്തനങ്ങൾ പ്രവർത്തിക്കണമെന്നില്ല."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"സിസ്‌റ്റത്തിനായി മതിയായ സംഭരണമില്ല. 250MB സൗജന്യ സംഭരണമുണ്ടെന്ന് ഉറപ്പുവരുത്തി പുനരാരംഭിക്കുക."</string>
@@ -1790,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM അനുവദനീയമല്ല"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ഫോൺ അനുവദനീയമല്ല"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"പോപ്പ് അപ്പ് വിൻഡോ"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index b088180..c89a3f9 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Админ апп байхгүй байгаа тул ажлын профайлыг устгасан байна"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Ажлын профайлын админ апп байхгүй эсвэл эвдэрсэн байна. Үүний улмаас таны ажлын профайл болон холбогдох мэдээллийг устгасан болно. Тусламж хэрэгтэй бол админтай холбогдоно уу."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Таны ажлын профайл энэ төхөөрөмжид боломжгүй байна"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Нууц үгийг хэт олон удаа буруу оруулсан байна"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Төхөөрөмжийг удирдсан"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Таны байгууллага энэ төхөөрөмжийг удирдаж, сүлжээний ачааллыг хянадаг. Дэлгэрэнгүй мэдээлэл авах бол товшино уу."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Таны төхөөрөмж устах болно."</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Сануулга"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Жижиглэнгийн жишээ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB холболт"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Апп ажиллаж байна"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Апп батерей ашиглаж байна"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> батерей ашиглаж байна"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батерей ашиглаж байна"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Оруулах арга"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Текст үйлдэл"</string>
     <string name="email" msgid="4560673117055050403">"Имэйл"</string>
-    <string name="dial" msgid="4204975095406423102">"Утас"</string>
-    <string name="map" msgid="6068210738233985748">"Газрын зураг"</string>
-    <string name="browse" msgid="6993590095938149861">"Хөтөч"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Харилцагч"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Сангийн хэмжээ дутагдаж байна"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Зарим систем функц ажиллахгүй байна"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Системд хангалттай сан байхгүй байна. 250MБ чөлөөтэй зай байгаа эсэхийг шалгаад дахин эхлүүлнэ үү."</string>
@@ -1788,4 +1793,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM боломжгүй"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Утас боломжгүй"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"гэнэт гарч ирэх цонх"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 9c74b30..8ef0f66 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"प्रशासक अॅप गहाळ असल्यामुळे कार्य प्रोफाइल हटवले गेले"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"कार्य प्रोफाइल प्रशासक अॅप गहाळ आहे किंवा करप्ट आहे. परिणामी, आपले कार्य प्रोफाइल आणि संबंधित डेटा हटवले गेले आहेत. सहाय्यासाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"आपले कार्य प्रोफाइल आता या डिव्हाइसवर उपलब्‍ध नाही"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"बर्‍याचदा पासवर्ड टाकण्‍याचा प्रयत्‍न केला"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"डिव्हाइस व्यवस्थापित केले आहे"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"आपली संस्था हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे निरीक्षण करू शकते. तपशीलांसाठी टॅप करा."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"तुमचे डिव्हाइस मिटविले जाईल"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"सूचना"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"रीटेल डेमो"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB कनेक्‍शन"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"अॅप्‍समुळे बॅटरी संपत आहे"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> बॅटरी वापरत आहे"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> अॅप्‍स बॅटरी वापरत आहेत"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"इनपुट पद्धत"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"मजकूर क्रिया"</string>
     <string name="email" msgid="4560673117055050403">"ईमेल"</string>
-    <string name="dial" msgid="4204975095406423102">"फोन"</string>
-    <string name="map" msgid="6068210738233985748">"नकाशे"</string>
-    <string name="browse" msgid="6993590095938149861">"ब्राउझर"</string>
-    <string name="sms" msgid="8250353543787396737">"एसएमएस"</string>
-    <string name="add_contact" msgid="7990645816259405444">"संपर्क"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"संचयन स्थान संपत आहे"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"काही सिस्टम कार्ये कार्य करू शकत नाहीत"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"सिस्टीमसाठी पुरेसे संचयन नाही. आपल्याकडे 250MB मोकळे स्थान असल्याचे सुनिश्चित करा आणि रीस्टार्ट करा."</string>
@@ -1790,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"सिमला अनुमती नाही"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"फोनला अनुमती नाही"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"पॉपअप विंडो"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index a81b76f..428f974 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Profil kerja dipadamkan kerana ketiadaan apl pentadbir"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Apl pentadbir profil kerja tiada atau rosak. Akibatnya, profil kerja anda dan data yang berkaitan telah dipadamkan. Hubungi pentadbir anda untuk mendapatkan bantuan."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Profil kerja anda tidak lagi tersedia pada peranti ini"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Terlalu banyak percubaan kata laluan"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Peranti ini diurus"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Organisasi anda mengurus peranti ini dan mungkin memantau trafik rangkaian. Ketik untuk mendapatkan butiran."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Peranti anda akan dipadam"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Makluman"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Tunjuk cara runcit"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Sambungan USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Apl berjalan"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apl yang menggunakan bateri"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang menggunakan bateri"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apl sedang menggunakan bateri"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Kaedah input"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
     <string name="email" msgid="4560673117055050403">"E-mel"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Peta"</string>
-    <string name="browse" msgid="6993590095938149861">"Penyemak imbas"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kenalan"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang storan semakin berkurangan"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak berfungsi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Tidak cukup storan untuk sistem. Pastikan anda mempunyai 250MB ruang kosong dan mulakan semula."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM tidak dibenarkan"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon tidak dibenarkan"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Tetingkap Timbul"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 34e783b..84d4172 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"စီမံခန့်ခွဲရန် အက်ပ်မရှိသောကြောင့် အလုပ်ပရိုဖိုင်ကို ဖျက်လိုက်ခြင်းဖြစ်သည်"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"အလုပ်ပရိုဖိုင် စီမံခန့်ခွဲရန်အက်ပ် မရှိပါ သို့မဟုတ် ပျက်စီးနေပါသည်။ ထို့ကြောင့် သင်၏ အလုပ်ပရိုဖိုင်နှင့် ဆက်စပ်နေသော ဒေတာများကို ဖျက်လိုက်ပါပြီ။ အကူအညီရယူရန် သင်၏စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"ဤစက်ပစ္စည်းတွင် သင်၏ အလုပ်ပရိုဖိုင်မရှိတော့ပါ"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"စကားဝှက်ထည့်သွင်းရန် ကြိုးစားသည့် အကြိမ်အရေအတွက် အလွန်များသွား၍ ဖြစ်ပါသည်"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"စက်ပစ္စည်းကို စီမံခန့်ခွဲထားပါသည်"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"ဤစက်ပစ္စည်းကို သင်၏ အဖွဲ့အစည်းက စီမံပြီး ကွန်ရက်အသွားအလာကို စောင့်ကြည့်နိုင်ပါသည်။ ထပ်မံလေ့လာရန် တို့ပါ။"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"သတိပေးချက်များ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"လက်လီအရောင်းဆိုင် သရုပ်ပြမှု"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB ချိတ်ဆက်မှု"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"APP လုပ်ဆောင်နေသည်"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"အက်ပ်များက ဘက်ထရီကုန်စေသည်"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> က ဘက်ထရီကို အသုံးပြုနေသည်"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"အက်ပ် <xliff:g id="NUMBER">%1$d</xliff:g> ခုက ဘက်ထရီကို အသုံးပြုနေသည်"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ထည့်သွင်းရန်နည်းလမ်း"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"စာတို လုပ်ဆောင်ချက်"</string>
     <string name="email" msgid="4560673117055050403">"အီးမေးလ်"</string>
-    <string name="dial" msgid="4204975095406423102">"ဖုန်း"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"ဘရောင်ဇာ"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS စာတိုစနစ်"</string>
-    <string name="add_contact" msgid="7990645816259405444">"အဆက်အသွယ်"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"သိမ်းဆည်သော နေရာ နည်းနေပါသည်"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"တချို့ စနစ်လုပ်ငန်းများ အလုပ် မလုပ်ခြင်း ဖြစ်နိုင်ပါသည်"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"စနစ်အတွက် သိုလှောင်ခန်း မလုံလောက်ပါ။ သင့်ဆီမှာ နေရာလွတ် ၂၅၀ MB ရှိတာ စစ်ကြည့်ပြီး စတင်ပါ။"</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"ဆင်းမ်ကို ခွင့်မပြုပါ"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ဖုန်းကို ခွင့်မပြုပါ"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"ပေါ့ပ်အပ် ဝင်းဒိုး"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 52436ea..232a60f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Jobbprofilen er slettet på grunn av manglende administratorapp"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Administratorappen for jobbprofilen mangler eller er skadet. Dette har ført til at jobbprofilen og alle data knyttet til den, har blitt slettet. Ta kontakt med administratoren for å få hjelp."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Jobbprofilen din er ikke lenger tilgjengelig på denne enheten"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"For mange passordforsøk"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Enheten administreres"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Organisasjonen din kontrollerer denne enheten og kan overvåke nettverkstrafikk. Trykk for å få mer informasjon."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Enheten blir slettet"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Varsler"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Butikkdemo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-tilkobling"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App kjører"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apper bruker batteri"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruker batteri"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apper bruker batteri"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Inndatametode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
     <string name="email" msgid="4560673117055050403">"E-post"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Kart"</string>
-    <string name="browse" msgid="6993590095938149861">"Nettleser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Lite ledig lagringsplass"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Enkelte systemfunksjoner fungerer muligens ikke slik de skal"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Det er ikke nok lagringsplass for systemet. Kontrollér at du har 250 MB ledig plass, og start på nytt."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-kortet er ikke tillatt"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefonen er ikke tillatt"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Forgrunnsvindu"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index bb84eae..5e9b861 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"प्रशासकीय अनुप्रयोग नभएकाले कार्य प्रोफाइल मेटाइयो"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"उक्त कार्य प्रोफाइलको प्रशासकीय अनुप्रयोग छैन वा बिग्रेको छ। त्यसले गर्दा, तपाईंको कार्य प्रोफाइल र सम्बन्धित डेटालाई मेटिएको छ। सहायताका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"तपाईंको कार्य प्रोफाइल अब उप्रान्त यस यन्त्रमा उपलब्ध छैन"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"पासवर्ड प्रविष्ट गर्ने अत्यधिक गलत प्रयासहरू भए"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"यन्त्र व्यवस्थित गरिएको छ"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"तपाईंको संगठनले यस यन्त्रको व्यवस्थापन गर्दछ र नेटवर्क ट्राफिकको अनुगमन गर्न सक्छ। विवरणहरूका लागि ट्याप गर्नुहोस्।"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"तपाईंको यन्त्र मेटिनेछ"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"अलर्टहरू"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"खुद्रा बिक्री सम्बन्धी डेमो"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB जडान"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"अनुप्रयोगहरूले ब्याट्री खपत गर्दै छन्"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले ब्याट्री प्रयोग गर्दै छ"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> अनुप्रयोगहरूले ब्याट्री प्रयोग गर्दै छन्"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"निवेश विधि"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"पाठ कार्यहरू"</string>
     <string name="email" msgid="4560673117055050403">"इमेल"</string>
-    <string name="dial" msgid="4204975095406423102">"फोन गर्नुहोस्"</string>
-    <string name="map" msgid="6068210738233985748">"नक्सा"</string>
-    <string name="browse" msgid="6993590095938149861">"ब्राउजर"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"सम्पर्क"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"भण्डारण ठाउँ सकिँदै छ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"सायद केही प्रणाली कार्यक्रमहरूले काम गर्दैनन्"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"प्रणालीको लागि पर्याप्त भण्डारण छैन। तपाईँसँग २५० मेगा बाइट ठाउँ खाली भएको निश्चित गर्नुहोस् र फेरि सुरु गर्नुहोस्।"</string>
@@ -1796,4 +1802,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM लाई अनुमति छैन"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"फोनलाई अनुमति छैन"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"पपअप विन्डो"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3f8ed59..efe7e3e 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Meldingen"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo voor de detailhandel"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-verbinding"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App actief"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps die de batterij gebruiken"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruikt de batterij"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps gebruiken de batterij"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Invoermethode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstacties"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefoon"</string>
-    <string name="map" msgid="6068210738233985748">"Kaarten"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"Sms"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contact"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Opslagruimte is bijna vol"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bepaalde systeemfuncties werken mogelijk niet"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Onvoldoende opslagruimte voor het systeem. Zorg ervoor dat je 250 MB vrije ruimte hebt en start opnieuw."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Simkaart niet toegestaan"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefoon niet toegestaan"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Pop-upvenster"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2c0ba4b..1072129 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"ਗੁੰਮਸ਼ੁਦਾ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਦੇ ਕਾਰਨ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਮਿਟਾਇਆ ਗਿਆ"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਜਾਂ ਤਾਂ ਗੁੰਮਸ਼ੁਦਾ ਹੈ ਜਾਂ ਖਰਾਬ ਹੈ। ਨਤੀਜੇ ਵਜੋਂ, ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਸਬੰਧਿਤ ਡਾਟਾ ਮਿਟਾਇਆ ਗਿਆ ਹੈ। ਸਹਾਇਤਾ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹੁਣ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"ਕਈ ਵਾਰ ਗਲਤ ਪਾਸਵਰਡ ਦਾਖਲ ਕੀਤਾ ਗਿਆ"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ ਅਧੀਨ ਹੈ"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"ਤੁਹਾਡਾ ਸੰਗਠਨ ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮਿਟਾਇਆ ਜਾਏਗਾ"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ਸੁਚੇਤਨਾਵਾਂ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ਪ੍ਰਚੂਨ ਸਟੋਰਾਂ ਲਈ ਡੈਮੋ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB ਕਨੈਕਸ਼ਨ"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ਬੈਟਰੀ ਦੀ ਖਪਤ ਕਰਨ ਵਾਲੀਆਂ ਐਪਾਂ"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ਐਪਾਂ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ਇਨਪੁੱਟ ਵਿਧੀ"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ਟੈਕਸਟ ਕਿਰਿਆਵਾਂ"</string>
     <string name="email" msgid="4560673117055050403">"ਈਮੇਲ ਕਰੋ"</string>
-    <string name="dial" msgid="4204975095406423102">"ਫ਼ੋਨ ਕਰੋ"</string>
-    <string name="map" msgid="6068210738233985748">"ਨਕਸ਼ੇ"</string>
-    <string name="browse" msgid="6993590095938149861">"ਬ੍ਰਾਊਜ਼ਰ"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"ਸੰਪਰਕ"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ਸਟੋਰੇਜ ਦੀ ਜਗ੍ਹਾ ਖਤਮ ਹੋ ਰਹੀ ਹੈ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ਕੁਝ ਸਿਸਟਮ ਫੰਕਸ਼ਨ ਕੰਮ ਨਹੀਂ ਵੀ ਕਰ ਸਕਦੇ"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ਸਿਸਟਮ ਲਈ ਲੋੜੀਂਦੀ ਸਟੋਰੇਜ ਨਹੀਂ ਹੈ। ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡੇ ਕੋਲ 250MB ਖਾਲੀ ਜਗ੍ਹਾ ਹੈ ਅਤੇ ਮੁੜ-ਚਾਲੂ ਕਰੋ।"</string>
@@ -1790,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ਫ਼ੋਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"ਪੌਪਅੱਪ ਵਿੰਡੋ"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 685ad53..361d383 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -176,8 +176,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Profil do pracy został usunięty z powodu braku aplikacji administratora"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Brakuje aplikacji administratora profilu do pracy lub jest ona uszkodzona. Dlatego Twój profil do pracy i związane z nim dane zostały usunięte. Skontaktuj się ze swoim administratorem, by uzyskać pomoc."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Twój profil do pracy nie jest już dostępny na tym urządzeniu"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Zbyt wiele prób podania hasła"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Urządzenie jest zarządzane"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Twoja organizacja zarządza tym urządzeniem i może monitorować ruch w sieci. Kliknij, by dowiedzieć się więcej."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Twoje urządzenie zostanie wyczyszczone"</string>
@@ -256,6 +255,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerty"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Tryb demo dla sklepów"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Połączenie USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Działa aplikacja"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacje zużywające baterię"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> zużywa baterię"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Liczba aplikacji zużywających baterię: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
@@ -1019,11 +1019,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Sposób wprowadzania tekstu"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Działania na tekście"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Mapy"</string>
-    <string name="browse" msgid="6993590095938149861">"Internet"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Kończy się miejsce"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektóre funkcje systemu mogą nie działać"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Za mało pamięci w systemie. Upewnij się, że masz 250 MB wolnego miejsca i uruchom urządzenie ponownie."</string>
@@ -1860,4 +1865,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Niedozwolona karta SIM"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Niedozwolony telefon"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Wyskakujące okienko"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 1a9eefb..81b5e57 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstração na loja"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexão USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App em execução"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps que estão consumindo a bateria"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão consumindo a bateria"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefone"</string>
-    <string name="map" msgid="6068210738233985748">"Mapas"</string>
-    <string name="browse" msgid="6993590095938149861">"Navegador"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contato"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Pouco espaço de armazenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema podem não funcionar"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Não há armazenamento suficiente para o sistema. Certifique-se de ter 250 MB de espaço livre e reinicie."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM não permitido"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Smartphone não permitido"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Janela pop-up"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"Mais <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 0f4635b..18d9c72 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstração para retalho"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Ligação USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplicação em execução"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicações que estão a consumir bateria"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"A aplicação <xliff:g id="APP_NAME">%1$s</xliff:g> está a consumir bateria."</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicações estão a consumir bateria."</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acções de texto"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
-    <string name="dial" msgid="4204975095406423102">"Telemóvel"</string>
-    <string name="map" msgid="6068210738233985748">"Mapas"</string>
-    <string name="browse" msgid="6993590095938149861">"Navegador"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contacto"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Está quase sem espaço de armazenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema poderão não funcionar"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Não existe armazenamento suficiente para o sistema. Certifique-se de que tem 250 MB de espaço livre e reinicie."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM não permitido"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telemóvel não permitido"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Janela pop-up"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1a9eefb..81b5e57 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstração na loja"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexão USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App em execução"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps que estão consumindo a bateria"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão consumindo a bateria"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefone"</string>
-    <string name="map" msgid="6068210738233985748">"Mapas"</string>
-    <string name="browse" msgid="6993590095938149861">"Navegador"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contato"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Pouco espaço de armazenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema podem não funcionar"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Não há armazenamento suficiente para o sistema. Certifique-se de ter 250 MB de espaço livre e reinicie."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM não permitido"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Smartphone não permitido"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Janela pop-up"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"Mais <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 298434c..e71b3ef 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -252,6 +252,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerte"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstrație comercială"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexiune USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplicația rulează"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicațiile consumă bateria"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> folosește bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicații folosesc bateria"</string>
@@ -998,11 +999,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Metodă de intrare"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acțiuni pentru text"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Hărți"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Persoană de contact"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Spațiul de stocare aproape ocupat"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Este posibil ca unele funcții de sistem să nu funcționeze"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Spațiu de stocare insuficient pentru sistem. Asigurați-vă că aveți 250 MB de spațiu liber și reporniți."</string>
@@ -1824,4 +1830,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Cardul SIM nu este permis"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefonul nu este permis"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Fereastră pop-up"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 643978e..4090e34 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -176,8 +176,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Рабочий профиль удален, поскольку отсутствует приложение для администрирования"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Приложение для администрирования рабочего профиля отсутствует или повреждено. Из-за этого рабочий профиль и связанные с ним данные были удалены. Если у вас возникли вопросы, обратитесь к администратору."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Ваш рабочий профиль больше не доступен на этом устройстве"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Слишком много попыток ввести пароль."</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Это управляемое устройство"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик. Подробнее…"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Все данные с устройства будут удалены"</string>
@@ -256,6 +255,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Уведомления"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Деморежим для магазина"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-подключение"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Приложение активно"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Приложения, расходующие заряд"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" расходует заряд"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Несколько приложений (<xliff:g id="NUMBER">%1$d</xliff:g>) расходуют заряд"</string>
@@ -1019,11 +1019,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Способ ввода"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Операции с текстом"</string>
     <string name="email" msgid="4560673117055050403">"Письмо"</string>
-    <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="6068210738233985748">"Карты"</string>
-    <string name="browse" msgid="6993590095938149861">"Браузер"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Контакт"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Недостаточно памяти"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некоторые функции могут не работать"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостаточно свободного места для системы. Освободите не менее 250 МБ дискового пространства и перезапустите устройство."</string>
@@ -1860,4 +1865,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Использование SIM-карты запрещено"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Звонки запрещены"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Всплывающее окно"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index e8b963c..d148100 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ඇඟවීම්"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"සිල්ලර ආදර්ශනය"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB සම්බන්ධතාවය"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"යෙදුම ධාවනය කරමින්"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"බැටරිය භාවිත කරන යෙදුම්"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> බැටරිය භාවිත කරයි"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"යෙදුම් <xliff:g id="NUMBER">%1$d</xliff:g>ක් බැටරිය භාවිත කරයි"</string>
@@ -980,11 +981,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ආදාන ක්‍රමය"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"පෙළ ක්‍රියාවන්"</string>
     <string name="email" msgid="4560673117055050403">"ඊ-තැපෑල"</string>
-    <string name="dial" msgid="4204975095406423102">"දුරකථනය"</string>
-    <string name="map" msgid="6068210738233985748">"සිතියම්"</string>
-    <string name="browse" msgid="6993590095938149861">"බ්‍රවුසරය"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"සම්බන්ධතා"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ආචයනය ඉඩ ප්‍රමාණය අඩු වී ඇත"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"සමහර පද්ධති කාර්යයන් ක්‍රියා නොකරනු ඇත"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"පද්ධතිය සඳහා ප්‍රමාණවත් ඉඩ නොමැත. ඔබට 250MB නිදහස් ඉඩක් තිබෙන ඔබට තිබෙන බව සහතික කරගෙන නැවත උත්සාහ කරන්න."</string>
@@ -1791,4 +1797,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM එක සඳහා ඉඩ නොදේ"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"දුරකථනය සඳහා ඉඩ නොදේ"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"උත්පතන කවුළුව"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 36ad8b9..f30b581 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -176,8 +176,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Pracovný profil bol odstránený z dôvodu chýbajúcej aplikácie na správu"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Aplikácia na správu pracovného profilu buď chýba, alebo je poškodená. Z toho dôvodu bol odstránený pracovný profil aj k nemu priradené dáta. Ak potrebujete pomoc, kontaktujte svojho správcu."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Váš pracovný profil už v tomto zariadení nie je k dispozícii"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Príliš veľa pokusov o zadanie hesla"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Zariadenie je spravované"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku. Klepnutím zobrazíte podrobnosti."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Vaše zariadenie bude vymazané"</string>
@@ -256,6 +255,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozornenia"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Predajná ukážka"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Pripojenie USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplikácia je spustená"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikácie spotrebúvajú batériu"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> používa batériu"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Aplikácie (<xliff:g id="NUMBER">%1$d</xliff:g>) používajú batériu"</string>
@@ -1019,11 +1019,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Metóda vstupu"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operácie s textom"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefón"</string>
-    <string name="map" msgid="6068210738233985748">"Mapy"</string>
-    <string name="browse" msgid="6993590095938149861">"Prehliadač"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nedostatok ukladacieho priestoru"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektoré systémové funkcie nemusia fungovať"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"V úložisku nie je dostatok voľného miesta pre systém. Zaistite, aby ste mali 250 MB voľného miesta a zariadenie reštartujte."</string>
@@ -1860,4 +1865,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM karta je zakázaná"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefón je zakázaný"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Automaticky otvárané okno"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 7ad6bc2..e92dadc 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -255,6 +255,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Opozorila"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Predstavitev za maloprodajo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Povezava USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplikacija se izvaja"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacije, ki porabljajo energijo akumulatorja"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> porablja energijo akumulatorja"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Toliko aplikacij porablja energijo akumulatorja: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
@@ -1018,11 +1019,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Način vnosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Besedilna dejanja"</string>
     <string name="email" msgid="4560673117055050403">"E-pošta"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Zemljevidi"</string>
-    <string name="browse" msgid="6993590095938149861">"Brskalnik"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Stik"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Prostor za shranjevanje bo pošel"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Nekatere sistemske funkcije morda ne delujejo"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"V shrambi ni dovolj prostora za sistem. Sprostite 250 MB prostora in znova zaženite napravo."</string>
@@ -1859,4 +1865,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Kartica SIM ni dovoljena"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon ni dovoljen"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Pojavno okno"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"in še <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 7f0a693..1b247e4 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Profili i punës u fshi për shkak të mungesës së aplikacionit të administratorit"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Aplikacioni i administratorit të profilit të punës mungon ose është dëmtuar. Si rezultat i kësaj, profili yt i punës dhe të dhënat përkatëse janë fshirë. Kontakto me administratorin për ndihmë."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Profili yt i punës nuk është më i disponueshëm në këtë pajisje"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Shumë përpjekje për fjalëkalimin"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Pajisja është e menaxhuar"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Organizata jote e menaxhon këtë pajisje dhe mund të monitorojë trafikun e rrjetit. Trokit për detaje."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Pajisja do të spastrohet"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Sinjalizimet"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstrimi i shitjes me pakicë"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Lidhja USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplikacioni është në ekzekutim"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacionet që konsumojnë baterinë"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> po përdor baterinë"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikacione po përdorin baterinë"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Metoda e hyrjes"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Veprimet e tekstit"</string>
     <string name="email" msgid="4560673117055050403">"Dërgo mail"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefoni"</string>
-    <string name="map" msgid="6068210738233985748">"Hartat"</string>
-    <string name="browse" msgid="6993590095938149861">"Shfletuesi"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakti"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Hapësira ruajtëse po mbaron"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Disa funksione të sistemit mund të mos punojnë"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nuk ka hapësirë të mjaftueshme ruajtjeje për sistemin. Sigurohu që të kesh 250 MB hapësirë të lirë dhe pastaj të rifillosh."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Karta SIM nuk lejohet"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefoni nuk lejohet"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Dritare kërcyese"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 1008215..ecb85d7 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -174,8 +174,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Профил за Work је избрисан јер недостаје апликација за администраторе"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Апликација за администраторе на профилу за Work недостаје или је оштећена. Због тога су профил за Work и повезани подаци избрисани. Обратите се администратору за помоћ."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Профил за Work више није доступан на овом уређају"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Превише покушаја уноса лозинке"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Уређајем се управља"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Организација управља овим уређајем и може да надгледа мрежни саобраћај. Додирните за детаље."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Уређај ће бити обрисан"</string>
@@ -253,6 +252,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Обавештења"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Режим демонстрације за малопродајне објекте"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB веза"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Апликација је покренута"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Апликације које троше батерију"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерију"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Апликације (<xliff:g id="NUMBER">%1$d</xliff:g>) користе батерију"</string>
@@ -999,11 +999,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Метод уноса"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Радње у вези са текстом"</string>
     <string name="email" msgid="4560673117055050403">"Пошаљи имејл"</string>
-    <string name="dial" msgid="4204975095406423102">"Позови"</string>
-    <string name="map" msgid="6068210738233985748">"Мапе"</string>
-    <string name="browse" msgid="6993590095938149861">"Прегледач"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Контакт"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Меморијски простор је на измаку"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Неке системске функције можда не функционишу"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Нема довољно меморијског простора за систем. Уверите се да имате 250 MB слободног простора и поново покрените."</string>
@@ -1825,4 +1830,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM картица није дозвољена"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Телефон није дозвољен"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Искачући прозор"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"и још <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 44a66f8..c0bd01a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Varningar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo för återförsäljare"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-anslutning"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App körs"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Appar som drar batteri"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> drar batteri"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> appar drar batteri"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Indatametod"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textåtgärder"</string>
     <string name="email" msgid="4560673117055050403">"Skicka e-post"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Kartor"</string>
-    <string name="browse" msgid="6993590095938149861">"Webbläsare"</string>
-    <string name="sms" msgid="8250353543787396737">"Sms"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Lagringsutrymmet börjar ta slut"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Det kan hända att vissa systemfunktioner inte fungerar"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Det finns inte tillräckligt med utrymme för systemet. Kontrollera att du har ett lagringsutrymme på minst 250 MB och starta om."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-kort tillåts inte"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Mobil tillåts inte"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"popup-fönster"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> till"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 9a78fd4..ebdf4ff 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -247,6 +247,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Arifa"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Onyesho la duka la rejareja"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Muunganisho wa USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Programu inaendelea kutekelezwa"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Programu zinazotumia betri"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumia betri"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Programu <xliff:g id="NUMBER">%1$d</xliff:g> zinatumia betri"</string>
@@ -976,11 +977,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Mbinu ya uingizaji"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Vitendo vya maandishi"</string>
     <string name="email" msgid="4560673117055050403">"Barua pepe"</string>
-    <string name="dial" msgid="4204975095406423102">"Simu"</string>
-    <string name="map" msgid="6068210738233985748">"Ramani"</string>
-    <string name="browse" msgid="6993590095938149861">"Kivinjari"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Anwani"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nafasi ya kuhifadhi inakaribia kujaa"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Baadhi ya vipengee vya mfumo huenda visifanye kazi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Hifadhi haitoshi kwa ajili ya mfumo. Hakikisha una MB 250 za nafasi ya hifadhi isiyotumika na uanzishe upya."</string>
@@ -1787,4 +1793,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM imekataliwa"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Simu imekataliwa"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Dirisha Ibukizi"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 1cd5cd0..03d64d0 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"நிர்வாகிப் பயன்பாடு இல்லாததால், பணி விவரம் நீக்கப்பட்டது"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"பணி விவர நிர்வாகிப் பயன்பாடு இல்லை அல்லது அது சிதைந்துள்ளது. இதன் விளைவாக, உங்கள் பணி விவரமும் அதனுடன் தொடர்புடைய தரவும் நீக்கப்பட்டன. உதவிக்கு, நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"இந்தச் சாதனத்தில் இனி பணி விவரம் கிடைக்காது"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"கடவுச்சொல்லை அதிக முறை தவறாக முயற்சித்துவிட்டீர்கள்"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"சாதனம் நிர்வகிக்கப்படுகிறது"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"உங்கள் நிறுவனம் இந்தச் சாதனத்தை நிர்வகிக்கும், அத்துடன் அது நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கலாம். விவரங்களுக்கு, தட்டவும்."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"சாதனத் தரவு அழிக்கப்படும்"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"விழிப்பூட்டல்கள்"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"விற்பனையாளர் டெமோ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB இணைப்பு"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"பேட்டரியைப் பயன்படுத்தும் பயன்பாடுகள்"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாடு பேட்டரியைப் பயன்படுத்துகிறது"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> பயன்பாடுகள் பேட்டரியைப் பயன்படுத்துகின்றன"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"உள்ளீட்டு முறை"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"உரை நடவடிக்கைகள்"</string>
     <string name="email" msgid="4560673117055050403">"மின்னஞ்சல்"</string>
-    <string name="dial" msgid="4204975095406423102">"ஃபோன்"</string>
-    <string name="map" msgid="6068210738233985748">"வரைபடம்"</string>
-    <string name="browse" msgid="6993590095938149861">"உலாவி"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"தொடர்பு"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"சேமிப்பிடம் குறைகிறது"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"சில அமைப்பு செயல்பாடுகள் வேலை செய்யாமல் போகலாம்"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"முறைமையில் போதுமான சேமிப்பகம் இல்லை. 250மெ.பை. அளவு காலி இடவசதி இருப்பதை உறுதிசெய்து மீண்டும் தொடங்கவும்."</string>
@@ -1790,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"சிம் அனுமதிக்கப்படவில்லை"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ஃபோன் அனுமதிக்கப்படவில்லை"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"பாப்அப் சாளரம்"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 9c1a529..8aac827 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"నిర్వాహక యాప్ లేనందున కార్యాలయ ప్రొఫైల్ తొలగించబడింది"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"కార్యాలయ ప్రొఫైల్ నిర్వాహక యాప్ లేదు లేదా పాడైంది. తత్ఫలితంగా, మీ కార్యాలయ ప్రొఫైల్ మరియు సంబంధిత డేటా తొలగించబడ్డాయి. సహాయం కోసం మీ నిర్వాహకులను సంప్రదించండి."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"ఈ పరికరంలో మీ కార్యాలయ ప్రొఫైల్ ఇప్పుడు అందుబాటులో లేదు"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"చాలా ఎక్కువ పాస్‌వర్డ్ ప్రయత్నాలు చేసారు"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"పరికరం నిర్వహించబడింది"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"మీ సంస్థ ఈ పరికరాన్ని నిర్వహిస్తుంది మరియు నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించవచ్చు. వివరాల కోసం నొక్కండి."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"మీ పరికరంలోని డేటా తొలగించబడుతుంది"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"హెచ్చరికలు"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"రిటైల్ డెమో"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB కనెక్షన్"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"యాప్ అమలవుతోంది"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"బ్యాటరీని ఉపయోగిస్తున్న యాప్‌లు"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> బ్యాటరీని ఉపయోగిస్తోంది"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> యాప్‌లు బ్యాటరీని ఉపయోగిస్తున్నాయి"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"ఇన్‌పుట్ పద్ధతి"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"వచనానికి సంబంధించిన చర్యలు"</string>
     <string name="email" msgid="4560673117055050403">"ఇమెయిల్"</string>
-    <string name="dial" msgid="4204975095406423102">"ఫోన్"</string>
-    <string name="map" msgid="6068210738233985748">"మ్యాప్స్"</string>
-    <string name="browse" msgid="6993590095938149861">"బ్రౌజర్"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"పరిచయం"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"నిల్వ ఖాళీ అయిపోతోంది"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"కొన్ని సిస్టమ్ కార్యాచరణలు పని చేయకపోవచ్చు"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"సిస్టమ్ కోసం తగినంత నిల్వ లేదు. మీకు 250MB ఖాళీ స్థలం ఉందని నిర్ధారించుకుని, పునఃప్రారంభించండి."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM అనుమతించబడదు"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ఫోన్ అనుమతించబడదు"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"పాప్అప్ విండో"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 900f950..c57335c 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"ลบโปรไฟล์งานแล้วเนื่องจากไม่มีแอปผู้ดูแลระบบ"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"แอปผู้ดูแลระบบโปรไฟล์งานไม่มีอยู่หรือเสียหาย ระบบจึงทำการลบโปรไฟล์งานและข้อมูลที่เกี่ยวข้องของคุณออก โปรดติดต่อผู้ดูแลระบบเพื่อรับความช่วยเหลือ"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"โปรไฟล์งานของคุณไม่สามารถใช้ในอุปกรณ์นี้อีกต่อไป"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"ลองป้อนรหัสผ่านหลายครั้งเกินไป"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"อุปกรณ์มีการจัดการ"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"องค์กรของคุณจัดการอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย แตะเพื่อดูรายละเอียด"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"ระบบจะลบข้อมูลในอุปกรณ์ของคุณ"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"การแจ้งเตือน"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"การสาธิตสำหรับผู้ค้าปลีก"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"การเชื่อมต่อ USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"แอปที่ทำงานอยู่"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"แอปหลายแอปกำลังใช้แบตเตอรี่"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังใช้แบตเตอรี่"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"แอป <xliff:g id="NUMBER">%1$d</xliff:g> แอปกำลังใช้แบตเตอรี่"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"วิธีป้อนข้อมูล"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"การทำงานของข้อความ"</string>
     <string name="email" msgid="4560673117055050403">"อีเมล"</string>
-    <string name="dial" msgid="4204975095406423102">"โทรศัพท์"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"เบราว์เซอร์"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"ติดต่อ"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"พื้นที่จัดเก็บเหลือน้อย"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"บางฟังก์ชันระบบอาจไม่ทำงาน"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"พื้นที่เก็บข้อมูลไม่เพียงพอสำหรับระบบ โปรดตรวจสอบว่าคุณมีพื้นที่ว่าง 250 MB แล้วรีสตาร์ท"</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"ไม่อนุญาตให้ใช้ซิม"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ไม่อนุญาตให้ใช้โทรศัพท์"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"หน้าต่างป๊อปอัป"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 267f2ed..188513f 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Na-delete ang profile sa trabaho dahil wala itong admin app"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Nawawala o nasira ang admin app ng profile sa trabaho. Dahil dito, na-delete ang profile mo sa trabaho at nauugnay na data. Makipag-ugnayan sa iyong admin para sa tulong."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Hindi na available sa device na ito ang iyong profile sa trabaho"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Masyadong maraming pagsubok sa password"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Pinamamahalaan ang device"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Pinamamahalaan ng iyong organisasyon ang device na ito, at maaari nitong subaybayan ang trapiko sa network. I-tap para sa mga detalye."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Buburahin ang iyong device"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Mga Alerto"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Koneksyon ng USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Tumatakbo ang app"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Mga app na kumokonsumo ng baterya"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Gumagamit ng baterya ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Gumagamit ng baterya ang <xliff:g id="NUMBER">%1$d</xliff:g> (na) app"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Pamamaraan ng pag-input"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Pagkilos ng teksto"</string>
     <string name="email" msgid="4560673117055050403">"Mag-email"</string>
-    <string name="dial" msgid="4204975095406423102">"Telepono"</string>
-    <string name="map" msgid="6068210738233985748">"Mga Mapa"</string>
-    <string name="browse" msgid="6993590095938149861">"Browser"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Contact"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nauubusan na ang puwang ng storage"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Maaaring hindi gumana nang tama ang ilang paggana ng system"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Walang sapat na storage para sa system. Tiyaking mayroon kang 250MB na libreng espasyo at i-restart."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Hindi pinahihintulutan ang SIM"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Hindi pinahihintulutan ang telepono"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Window ng Popup"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 3d592fe..4396280 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Eksik yönetici uygulaması nedeniyle iş profili silindi"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"İş profili yönetici uygulaması eksik ya da bozuk. Bunun sonucunda iş profiliniz ve ilgili veriler silindi. Yardım almak için yöneticiniz ile iletişim kurun."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"İş profiliniz arık bu cihazda kullanılamıyor"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Çok fazla şifre denemesi yapıldı"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Cihaz yönetiliyor"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Kuruluşunuz bu cihazı yönetmekte olup ağ trafiğini izleyebilir. Ayrıntılar için dokunun."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Cihazınız silinecek"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Uyarılar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Mağaza demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB bağlantısı"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Uygulama çalışıyor"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Pil kullanan uygulamalar"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> pil kullanıyor"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> uygulama pil kullanıyor"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Giriş yöntemi"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Metin eylemleri"</string>
     <string name="email" msgid="4560673117055050403">"E-posta"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Haritalar"</string>
-    <string name="browse" msgid="6993590095938149861">"Tarayıcı"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kişi"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Depolama alanı bitiyor"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bazı sistem işlevleri çalışmayabilir"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sistem için yeterli depolama alanı yok. 250 MB boş alanınızın bulunduğundan emin olun ve yeniden başlatın."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM\'e izin verilmiyor"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefona izin verilmiyor"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Pop-up Pencere"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index a00f488..15e42bf 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -255,6 +255,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Сповіщення"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демо-режим для роздрібної торгівлі"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"З’єднання USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Працює додаток"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Додатки, що використовують заряд акумулятора"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> використовує заряд акумулятора"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Додатків, що використовують заряд акумулятора: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
@@ -1018,11 +1019,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Метод введення"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дії з текстом"</string>
     <string name="email" msgid="4560673117055050403">"Електронна пошта"</string>
-    <string name="dial" msgid="4204975095406423102">"Телефонувати"</string>
-    <string name="map" msgid="6068210738233985748">"Карти"</string>
-    <string name="browse" msgid="6993590095938149861">"Веб-переглядач"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Контакт"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Закінчується пам’ять"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Деякі системні функції можуть не працювати"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостатньо місця для системи. Переконайтесь, що на пристрої є 250 МБ вільного місця, і повторіть спробу."</string>
@@ -1859,4 +1865,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-карта заборонена"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Телефон заборонено"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Спливаюче вікно"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 4e528bd..2269ef5 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"گمشدہ منتظم ایپ کی وجہ سے دفتری پروفائل حذف کر دیا گیا"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"دفتری پروفائل کی منتظم ایپ یا تو غائب ہے یا خراب ہے۔ اس کی وجہ سے، آپ کا دفتری پروفائل اور متعلقہ ڈیٹا حذف کر دیے گئے ہیں۔ مدد کیلئے اپنے منتظم سے رابطہ کریں۔"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"آپ کا دفتری پروفائل اس آلہ پر مزید دستیاب نہیں ہے"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"پاس ورڈ کی بہت ساری کوششیں"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"آلہ زیر انتظام ہے"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"آپ کی تنظیم اس آلے کا نظم کرتی ہے اور وہ نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے۔ تفاصیل کیلئے تھپتھپائیں۔"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"آپ کا آلہ صاف کر دیا جائے گا"</string>
@@ -250,6 +249,8 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"الرٹس"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ریٹیل ڈیمو"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"‏USB کنکشن"</string>
+    <!-- no translation found for notification_channel_heavy_weight_app (6218742927792852607) -->
+    <skip />
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ایپس بیٹری خرچ کر رہی ہیں"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> بیٹری کا استعمال کر رہی ہے"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ایپس بیٹری کا استعمال کر رہی ہیں"</string>
@@ -979,11 +980,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"اندراج کا طریقہ"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"متن کی کارروائیاں"</string>
     <string name="email" msgid="4560673117055050403">"ای میل"</string>
-    <string name="dial" msgid="4204975095406423102">"فون کریں"</string>
-    <string name="map" msgid="6068210738233985748">"Maps"</string>
-    <string name="browse" msgid="6993590095938149861">"براؤزر"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"رابطہ"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"اسٹوریج کی جگہ ختم ہو رہی ہے"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ممکن ہے سسٹم کے کچھ فنکشنز کام نہ کریں"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"‏سسٹم کیلئے کافی اسٹوریج نہیں ہے۔ اس بات کو یقینی بنائیں کہ آپ کے پاس 250MB خالی جگہ ہے اور دوبارہ شروع کریں۔"</string>
@@ -1790,4 +1796,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"‏SIM کی اجازت نہیں ہے"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"فون کی اجازت نہیں ہے"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"پاپ اپ ونڈو"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"‎‎‎‎‎+ <xliff:g id="NUMBER">%1$d</xliff:g>‎‎"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index a269630..5bfd88b 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ogohlantirishlar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo rejim"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB orqali ulanish"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Ilova ishlamoqda"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Batareya quvvatini sarflayotgan ilovalar"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi batareya quvvatini sarflamoqda"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ta ilova batareya quvvatini sarflamoqda"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Kiritish uslubi"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Matn yozish"</string>
     <string name="email" msgid="4560673117055050403">"E-pochta"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="6068210738233985748">"Xaritalar"</string>
-    <string name="browse" msgid="6993590095938149861">"Brauzer"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Kontakt"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Xotirada bo‘sh joy tugamoqda"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Ba‘zi tizim funksiyalari ishlamasligi mumkin"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Tizim uchun xotirada joy yetarli emas. Avval 250 megabayt joy bo‘shatib, keyin qurilmani o‘chirib yoqing."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM karta ishlatish taqiqlangan"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Chaqiruvlar taqiqlangan"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Qalqib chiquvchi oyna"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 09df823..92bd320 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Đã xóa hồ sơ công việc do thiếu ứng dụng quản trị"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Ứng dụng quản trị hồ sơ công việc bị thiếu hoặc hỏng. Do vậy, hồ sơ công việc của bạn và dữ liệu liên quan đã bị xóa. Hãy liên hệ với quản trị viên của bạn để được trợ giúp."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Hồ sơ công việc của bạn không có sẵn trên thiết bị này nữa"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Quá nhiều lần nhập mật khẩu"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Thiết bị được quản lý"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"Tổ chức của bạn sẽ quản lý thiết bị này và có thể theo dõi lưu lượng truy cập mạng. Nhấn để biết chi tiết."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Thiết bị của bạn sẽ bị xóa"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Cảnh báo"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Giới thiệu bán lẻ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Kết nối USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Ứng dụng đang chạy"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Các ứng dụng tiêu thụ pin"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang sử dụng pin"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ứng dụng đang sử dụng pin"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Phương thức nhập"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tác vụ văn bản"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
-    <string name="dial" msgid="4204975095406423102">"Điện thoại"</string>
-    <string name="map" msgid="6068210738233985748">"Bản đồ"</string>
-    <string name="browse" msgid="6993590095938149861">"Trình duyệt"</string>
-    <string name="sms" msgid="8250353543787396737">"SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Liên hệ"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Sắp hết dung lượng lưu trữ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Một số chức năng hệ thống có thể không hoạt động"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Không đủ bộ nhớ cho hệ thống. Đảm bảo bạn có 250 MB dung lượng trống và khởi động lại."</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM không được cho phép"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Điện thoại không được cho phép"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Cửa sổ bật lên"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index b3c1af5..598b751 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"由于缺少管理应用,工作资料已被删除"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"工作资料管理应用缺失或损坏,因此系统已删除您的工作资料及相关数据。如需帮助,请与您的管理员联系。"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"您的工作资料已不在此设备上"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"密码尝试次数过多"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"设备为受管理设备"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"贵单位会管理该设备,且可能会监控网络流量。点按即可了解详情。"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"系统将清空您的设备"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"提醒"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售演示模式"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 连接"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"应用正在运行中"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"消耗电量的应用"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g>正在消耗电量"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> 个应用正在消耗电量"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"输入法"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string>
     <string name="email" msgid="4560673117055050403">"电子邮件"</string>
-    <string name="dial" msgid="4204975095406423102">"电话"</string>
-    <string name="map" msgid="6068210738233985748">"地图"</string>
-    <string name="browse" msgid="6993590095938149861">"浏览器"</string>
-    <string name="sms" msgid="8250353543787396737">"短信"</string>
-    <string name="add_contact" msgid="7990645816259405444">"联系人"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"存储空间不足"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"某些系统功能可能无法正常使用"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"系统存储空间不足。请确保您有250MB的可用空间,然后重新启动。"</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"不受允许的 SIM 卡"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"不受允许的手机"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"弹出式窗口"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 04a62a6..e9d9139 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"由於沒有管理員應用程式,工作設定檔已刪除"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"工作設定檔管理員應用程式已遺失或損毀。因此,您的工作設定檔和相關資料已刪除。請聯絡您的管理員以取得協助。"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"您的工作設定檔無法再在此裝置上使用"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"密碼輸入錯誤的次數過多"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"裝置已受管理"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"您的機構會管理此裝置,並可能會監控網絡流量。輕按即可瞭解詳情。"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"您的裝置將被清除"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"通知"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售示範"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 連線"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"應用程式正在執行"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"耗用電量的應用程式"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在使用電量"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在使用電量"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"輸入法"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string>
     <string name="email" msgid="4560673117055050403">"電郵"</string>
-    <string name="dial" msgid="4204975095406423102">"撥打電話"</string>
-    <string name="map" msgid="6068210738233985748">"地圖"</string>
-    <string name="browse" msgid="6993590095938149861">"瀏覽器"</string>
-    <string name="sms" msgid="8250353543787396737">"短訊"</string>
-    <string name="add_contact" msgid="7990645816259405444">"聯絡人"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"儲存空間即將用盡"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"部分系統功能可能無法運作"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"系統儲存空間不足。請確認裝置有 250 MB 的可用空間,然後重新啟動。"</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"不允許使用 SIM 卡"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"不允許使用手機"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"彈出式視窗"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 0e9827a..8108f75 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -172,8 +172,7 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"Work 設定檔因管理員應用程式遺失而遭到刪除"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Work 設定檔管理員應用程式遺失或已毀損,因此系統刪除了你的 Work 設定檔和相關資料。如需協助,請與你的管理員聯絡。"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"你的 Work 設定檔已不在這個裝置上"</string>
-    <!-- no translation found for work_profile_deleted_reason_maximum_password_failure (8986903510053359694) -->
-    <skip />
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"密碼輸入錯誤的次數過多"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"裝置受到管理"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"貴機構會管理這個裝置,且可能監控網路流量。輕觸即可瞭解詳情。"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"你的裝置資料將遭到清除"</string>
@@ -250,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"快訊"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售商示範模式"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 連線"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"應用程式執行中"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"正在耗用電量的應用程式"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在耗用電量"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在耗用電量"</string>
@@ -979,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"輸入法"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字動作"</string>
     <string name="email" msgid="4560673117055050403">"電子郵件"</string>
-    <string name="dial" msgid="4204975095406423102">"電話"</string>
-    <string name="map" msgid="6068210738233985748">"地圖"</string>
-    <string name="browse" msgid="6993590095938149861">"瀏覽器"</string>
-    <string name="sms" msgid="8250353543787396737">"簡訊"</string>
-    <string name="add_contact" msgid="7990645816259405444">"聯絡人"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"儲存空間即將用盡"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"部分系統功能可能無法運作"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"系統儲存空間不足。請確定你已釋出 250MB 的可用空間,然後重新啟動。"</string>
@@ -1790,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"不受允許的 SIM 卡"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"不受允許的手機"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"彈出式視窗"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index f341da1..56f7fc8 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -249,6 +249,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Izexwayiso"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Idemo yokuthenga"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Ukuxhumeka kwe-USB"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Uhlelo loksuebenza olusebenzayo"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Izinhlelo zokusebenza ezidla ibhethri"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> isebenzisa ibhethri"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> izinhlelo zokusebenza zisebenzisa ibhethri"</string>
@@ -978,11 +979,16 @@
     <string name="inputMethod" msgid="1653630062304567879">"Indlela yokufakwayo"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Izenzo zombhalo"</string>
     <string name="email" msgid="4560673117055050403">"I-imeyili"</string>
-    <string name="dial" msgid="4204975095406423102">"Ifoni"</string>
-    <string name="map" msgid="6068210738233985748">"Amamephu"</string>
-    <string name="browse" msgid="6993590095938149861">"Isiphequluli"</string>
-    <string name="sms" msgid="8250353543787396737">"I-SMS"</string>
-    <string name="add_contact" msgid="7990645816259405444">"Oxhumana naye"</string>
+    <!-- no translation found for dial (1253998302767701559) -->
+    <skip />
+    <!-- no translation found for map (6521159124535543457) -->
+    <skip />
+    <!-- no translation found for browse (1245903488306147205) -->
+    <skip />
+    <!-- no translation found for sms (4560537514610063430) -->
+    <skip />
+    <!-- no translation found for add_contact (7867066569670597203) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Isikhala sokulondoloza siyaphela"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Eminye imisebenzi yohlelo ingahle ingasebenzi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Akusona isitoreji esanele sesistimu. Qiniseka ukuthi unesikhala esikhululekile esingu-250MB uphinde uqalise kabusha."</string>
@@ -1789,4 +1795,13 @@
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"I-SIM ayivunyelwe"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Ifoni ayivunyelwe"</string>
     <string name="popup_window_default_title" msgid="4874318849712115433">"Iwindi lesigelekeqe"</string>
+    <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) -->
+    <skip />
+    <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 11cdb76..4b9839f 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2546,16 +2546,24 @@
         <attr name="filterTouchesWhenObscured" format="boolean" />
 
         <!-- Defines the quality of translucent drawing caches. This property is used
-             only when the drawing cache is enabled and translucent. The default value is auto. -->
+             only when the drawing cache is enabled and translucent. The default value is auto.
+             Deprecated: The view drawing cache was largely made obsolete with the introduction of
+             hardware-accelerated rendering in API 11. -->
         <attr name="drawingCacheQuality">
             <!-- Lets the framework decide what quality level should be used
-                 for the drawing cache. -->
+                 for the drawing cache.
+                 Deprecated: The view drawing cache was largely made obsolete with the introduction
+                 of hardware-accelerated rendering in API 11. -->
             <enum name="auto" value="0" />
             <!-- Low quality. When set to low quality, the drawing cache uses a lower color
-                 depth, thus losing precision in rendering gradients, but uses less memory. -->
+                 depth, thus losing precision in rendering gradients, but uses less memory.
+                 Deprecated: The view drawing cache was largely made obsolete with the introduction
+                 of hardware-accelerated rendering in API 11. -->
             <enum name="low" value="1" />
             <!-- High quality. When set to high quality, the drawing cache uses a higher
-                 color depth but uses more memory. -->
+                 color depth but uses more memory.
+                 Deprecated: The view drawing cache was largely made obsolete with the introduction
+                 of hardware-accelerated rendering in API 11. -->
             <enum name="high" value="2" />
         </attr>
 
@@ -3060,7 +3068,9 @@
              instance during a scrolling.) This property lets you persist the cache
              in memory after its initial usage. Persisting the cache consumes more
              memory but may prevent frequent garbage collection is the cache is created
-             over and over again. By default the persistence is set to scrolling. -->
+             over and over again. By default the persistence is set to scrolling.
+             Deprecated: The view drawing cache was largely made obsolete with the introduction of
+             hardware-accelerated rendering in API 11. -->
         <attr name="persistentDrawingCache">
             <!-- The drawing cache is not persisted after use. -->
             <flag name="none" value="0x0" />
@@ -3072,7 +3082,9 @@
             <flag name="all" value="0x3" />
         </attr>
         <!-- Defines whether the ViewGroup should always draw its children using their
-             drawing cache or not. The default value is true. -->
+             drawing cache or not. The default value is true.
+             Deprecated: The view drawing cache was largely made obsolete with the introduction of
+             hardware-accelerated rendering in API 11. -->
         <attr name="alwaysDrawnWithCache" format="boolean" />
         <!-- Sets whether this ViewGroup's drawable states also include
              its children's drawable states.  This is used, for example, to
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index e6c829f..0e90287 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1449,8 +1449,7 @@
              quit it.  Only one such app can be running at a time; if the user
              tries to launch a second such app, they will be prompted
              to quit the first before doing so.  While the
-             application is running, the user will be informed of this.
-             @hide -->
+             application is running, the user will be informed of this. -->
         <attr name="cantSaveState" format="boolean" />
         <attr name="uiOptions" />
         <!-- Declare that your application will be able to deal with RTL (right to left) layouts.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index dcb56a2..570f37c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2352,9 +2352,37 @@
     <!-- Package name for default network scorer app; overridden by product overlays. -->
     <string name="config_defaultNetworkScorerPackageName"></string>
 
-    <!-- default device has recents property -->
+    <!-- Determines whether recent tasks are provided to the user. Default device has recents
+         property. If this is false, then the following recents config flags are ignored. -->
     <bool name="config_hasRecents">true</bool>
 
+    <!-- The minimum number of visible recent tasks to be presented to the user through the
+         SystemUI. Can be -1 if there is no minimum limit. -->
+    <integer name="config_minNumVisibleRecentTasks_grid">-1</integer>
+
+    <!-- The maximum number of visible recent tasks to be presented to the user through the
+         SystemUI. Can be -1 if there is no maximum limit. -->
+    <integer name="config_maxNumVisibleRecentTasks_grid">9</integer>
+
+    <!-- The minimum number of visible recent tasks to be presented to the user through the
+         SystemUI. Can be -1 if there is no minimum limit. -->
+    <integer name="config_minNumVisibleRecentTasks_lowRam">-1</integer>
+
+    <!-- The maximum number of visible recent tasks to be presented to the user through the
+         SystemUI. Can be -1 if there is no maximum limit. -->
+    <integer name="config_maxNumVisibleRecentTasks_lowRam">9</integer>
+
+    <!-- The minimum number of visible recent tasks to be presented to the user through the
+         SystemUI. Can be -1 if there is no minimum limit. -->
+    <integer name="config_minNumVisibleRecentTasks">5</integer>
+
+    <!-- The maximum number of visible recent tasks to be presented to the user through the
+         SystemUI. Can be -1 if there is no maximum limit. -->
+    <integer name="config_maxNumVisibleRecentTasks">-1</integer>
+
+    <!-- The duration in which a recent task is considered in session and should be visible. -->
+    <integer name="config_activeTaskDurationHours">6</integer>
+
     <!-- default window ShowCircularMask property -->
     <bool name="config_windowShowCircularMask">false</bool>
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 108ac1c..0364b81 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2745,18 +2745,6 @@
 
   <!-- ===============================================================
        Resources added in version O of the platform
-
-       NOTE: add <public> elements within a <public-group> like so:
-
-       <public-group type="attr" first-id="0x01010531">
-           <public name="exampleAttr1" />
-           <public name="exampleAttr2" />
-       </public-group>
-
-       To add a new public-group block, choose an id value that is 1 greater
-       than the last of that item above. For example, the last "attr" id
-       value above is 0x01010530, so the public-group of attrs below has
-       the id value of 0x01010531.
        =============================================================== -->
     <eat-comment />
 
@@ -2827,18 +2815,6 @@
 
   <!-- ===============================================================
        Resources added in version O MR1 of the platform
-
-       NOTE: add <public> elements within a <public-group> like so:
-
-       <public-group type="attr" first-id="0x01010531">
-           <public name="exampleAttr1" />
-           <public name="exampleAttr2" />
-       </public-group>
-
-       To add a new public-group block, choose an id value that is 1 greater
-       than the last of that item above. For example, the last "attr" id
-       value above is 0x01010530, so the public-group of attrs below has
-       the id value of 0x01010531.
        =============================================================== -->
     <eat-comment />
 
@@ -2868,6 +2844,7 @@
     <eat-comment />
 
     <public-group type="attr" first-id="0x0101056e">
+      <public name="cantSaveState" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e0">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5189e7f..baede1a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -591,6 +591,11 @@
     <!-- Text shown when viewing channel settings for notifications related to a usb connection -->
     <string name="notification_channel_usb">USB connection</string>
 
+    <!-- Text shown when viewing channel settings for notification about a heavy-weight app
+         currently running.
+         [CHAR_LIMIT=NONE] -->
+    <string name="notification_channel_heavy_weight_app">App running</string>
+
     <!-- This is the label for the notification channel settings that controls the behavior
         of the notification about applications that are running in the background (that is,
         perhaps confusingly, running foreground services but not the foreground UI on the screen).
@@ -2101,12 +2106,6 @@
     <!-- Do not translate.  datepicker mode, overridden for watch -->
     <string name="date_picker_mode" translatable="false">"calendar"</string>
 
-    <!-- Do not translate.  WebView User Agent string -->
-    <string name="web_user_agent" translatable="false">Mozilla/5.0 (Linux; U; <xliff:g id="x">Android %s</xliff:g>)
-        AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.30</string>
-    <!-- Do not translate.  WebView User Agent targeted content -->
-    <string name="web_user_agent_target_content" translatable="false">"Mobile "</string>
-
     <!-- Title for a JavaScript dialog. "The page at <url of current page> says:" -->
     <string name="js_dialog_title">The page at \"<xliff:g id="title">%s</xliff:g>\" says:</string>
     <!-- Default title for a javascript dialog -->
@@ -2678,19 +2677,19 @@
     <string name="email">Email</string>
 
     <!-- Label for item in the text selection menu to trigger a Dialer app [CHAR LIMIT=20] -->
-    <string name="dial">Phone</string>
+    <string name="dial">Call</string>
 
     <!-- Label for item in the text selection menu to trigger a Map app [CHAR LIMIT=20] -->
-    <string name="map">Maps</string>
+    <string name="map">Locate</string>
 
     <!-- Label for item in the text selection menu to trigger a Browser app [CHAR LIMIT=20] -->
-    <string name="browse">Browser</string>
+    <string name="browse">Open</string>
 
     <!-- Label for item in the text selection menu to trigger an SMS app [CHAR LIMIT=20] -->
-    <string name="sms">SMS</string>
+    <string name="sms">Message</string>
 
     <!-- Label for item in the text selection menu to trigger adding a contact [CHAR LIMIT=20] -->
-    <string name="add_contact">Contact</string>
+    <string name="add_contact">Add</string>
 
     <!-- If the device is getting low on internal storage, a notification is shown to the user.  This is the title of that notification. -->
     <string name="low_internal_storage_view_title">Storage space running out</string>
@@ -4730,4 +4729,28 @@
 
     <!-- Format string for indicating there is more content in a slice view -->
     <string name="slice_more_content">+ <xliff:g id="number" example="5">%1$d</xliff:g></string>
+
+    <!--
+    A toast message shown when an app shortcut that was restored from a previous device is clicked,
+    but it cannot be started because the shortcut was created by a newer version of the app.
+    -->
+    <string name="shortcut_restored_on_lower_version">This shortcut requires latest app</string>
+
+    <!--
+    A toast message shown when an app shortcut that was restored from a previous device is clicked,
+    but it cannot be started because the shortcut was created by an app that doesn't support backup
+    and restore.
+    -->
+    <string name="shortcut_restore_not_supported">Couldn\u2019t restore shortcut because app doesn\u2019t support backup and restore</string>
+
+    <!--
+    A toast message shown when an app shortcut that was restored from a previous device is clicked,
+    but it cannot be started because the shortcut was created by an app with a different signature.
+    -->
+    <string name="shortcut_restore_signature_mismatch">Couldn\u2019t restore shortcut because of app signature mismatch</string>
+
+    <!--
+    A toast message shown when an app shortcut that wasn't restored due to an unknown issue is clicked,
+    -->
+    <string name="shortcut_restore_unknown_issue">Couldn\u2019t restore shortcut</string>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 53d09d8..1307ae2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -311,6 +311,13 @@
   <java-symbol type="bool" name="config_enableMultiUserUI"/>
   <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
   <java-symbol type="bool" name="config_hasRecents" />
+  <java-symbol type="integer" name="config_minNumVisibleRecentTasks_lowRam" />
+  <java-symbol type="integer" name="config_maxNumVisibleRecentTasks_lowRam" />
+  <java-symbol type="integer" name="config_minNumVisibleRecentTasks_grid" />
+  <java-symbol type="integer" name="config_maxNumVisibleRecentTasks_grid" />
+  <java-symbol type="integer" name="config_minNumVisibleRecentTasks" />
+  <java-symbol type="integer" name="config_maxNumVisibleRecentTasks" />
+  <java-symbol type="integer" name="config_activeTaskDurationHours" />
   <java-symbol type="bool" name="config_windowShowCircularMask" />
   <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
   <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
@@ -987,8 +994,6 @@
   <java-symbol type="string" name="volume_icon_description_notification" />
   <java-symbol type="string" name="volume_icon_description_ringer" />
   <java-symbol type="string" name="wait" />
-  <java-symbol type="string" name="web_user_agent" />
-  <java-symbol type="string" name="web_user_agent_target_content" />
   <java-symbol type="string" name="webpage_unresponsive" />
   <java-symbol type="string" name="whichApplication" />
   <java-symbol type="string" name="whichHomeApplication" />
@@ -3033,6 +3038,7 @@
   <java-symbol type="string" name="notification_channel_alerts" />
   <java-symbol type="string" name="notification_channel_retail_mode" />
   <java-symbol type="string" name="notification_channel_usb" />
+  <java-symbol type="string" name="notification_channel_heavy_weight_app" />
   <java-symbol type="string" name="config_defaultAutofillService" />
 
   <java-symbol type="string" name="notification_channel_foreground_service" />
@@ -3115,4 +3121,9 @@
   <java-symbol type="dimen" name="slice_icon_size" />
   <java-symbol type="dimen" name="slice_padding" />
   <java-symbol type="string" name="slice_more_content" />
+
+  <java-symbol type="string" name="shortcut_restored_on_lower_version" />
+  <java-symbol type="string" name="shortcut_restore_not_supported" />
+  <java-symbol type="string" name="shortcut_restore_signature_mismatch" />
+  <java-symbol type="string" name="shortcut_restore_unknown_issue" />
 </resources>
diff --git a/core/res/res/xml/default_zen_mode_config.xml b/core/res/res/xml/default_zen_mode_config.xml
index 5f4199a..1e4c03e 100644
--- a/core/res/res/xml/default_zen_mode_config.xml
+++ b/core/res/res/xml/default_zen_mode_config.xml
@@ -19,5 +19,5 @@
 
 <!-- Default configuration for zen mode.  See android.service.notification.ZenModeConfig. -->
 <zen version="2">
-    <allow calls="true" messages="false" reminders="true" events="true" />
+    <allow alarms="true" media_system_other="true" calls="false" messages="false" reminders="false" events="false" />
 </zen>
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index dbc9e5d..15eab1f 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -36,7 +36,8 @@
     ub-uiautomator \
     platform-test-annotations \
     compatibility-device-util \
-    truth-prebuilt
+    truth-prebuilt \
+    print-test-util-lib
 
 LOCAL_JAVA_LIBRARIES := android.test.runner conscrypt telephony-common org.apache.http.legacy
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index ac5d224..9c0543b 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -102,6 +102,7 @@
     <!-- os storage test permissions -->
     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
     <uses-permission android:name="android.permission.ASEC_ACCESS" />
+    <uses-permission android:name="android.permission.ASEC_ACCESS" />
     <uses-permission android:name="android.permission.ASEC_CREATE" />
     <uses-permission android:name="android.permission.ASEC_DESTROY" />
     <uses-permission android:name="android.permission.ASEC_MOUNT_UNMOUNT" />
@@ -1345,10 +1346,12 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="android.print.PrintTestActivity"/>
+        <activity
+            android:name="android.print.test.PrintDocumentActivity"
+            android:theme="@style/Theme" />
 
         <service
-            android:name="android.print.mockservice.MockPrintService"
+            android:name="android.print.test.services.FirstPrintService"
             android:permission="android.permission.BIND_PRINT_SERVICE">
             <intent-filter>
                 <action android:name="android.printservice.PrintService" />
@@ -1360,9 +1363,10 @@
         </service>
 
         <activity
-            android:name="android.print.mockservice.SettingsActivity"
+            android:name="android.print.test.services.SettingsActivity"
             android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
-            android:exported="true">
+            android:exported="true"
+            android:theme="@style/Theme">
         </activity>
 
         <activity
diff --git a/core/tests/coretests/src/android/print/BasePrintTest.java b/core/tests/coretests/src/android/print/BasePrintTest.java
deleted file mode 100644
index a70c604..0000000
--- a/core/tests/coretests/src/android/print/BasePrintTest.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.print;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doCallRealMethod;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.CancellationSignal;
-import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
-import android.print.mockservice.PrintServiceCallbacks;
-import android.print.mockservice.PrinterDiscoverySessionCallbacks;
-import android.print.mockservice.StubbablePrinterDiscoverySession;
-import android.printservice.CustomPrinterIconCallback;
-import android.printservice.PrintJob;
-import android.printservice.PrintService;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.rule.ActivityTestRule;
-import android.support.test.uiautomator.UiDevice;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.mockito.stubbing.Answer;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This is the base class for print tests.
- */
-abstract class BasePrintTest {
-    protected static final long OPERATION_TIMEOUT = 30000;
-    private static final String PM_CLEAR_SUCCESS_OUTPUT = "Success";
-    private static final int CURRENT_USER_ID = -2; // Mirrors UserHandle.USER_CURRENT
-
-    private android.print.PrintJob mPrintJob;
-
-    private CallCounter mStartCallCounter;
-    private CallCounter mStartSessionCallCounter;
-
-    private static Instrumentation sInstrumentation;
-    private static UiDevice sUiDevice;
-
-    @Rule
-    public ActivityTestRule<PrintTestActivity> mActivityRule =
-            new ActivityTestRule<>(PrintTestActivity.class, false, true);
-
-    /**
-     * {@link Runnable} that can throw and {@link Exception}
-     */
-    interface Invokable {
-        /**
-         * Execute the invokable
-         *
-         * @throws Exception
-         */
-        void run() throws Exception;
-    }
-
-    /**
-     * Assert that the invokable throws an expectedException
-     *
-     * @param invokable The {@link Invokable} to run
-     * @param expectedClass The {@link Exception} that is supposed to be thrown
-     */
-    void assertException(Invokable invokable, Class<? extends Exception> expectedClass)
-            throws Exception {
-        try {
-            invokable.run();
-        } catch (Exception e) {
-            if (e.getClass().isAssignableFrom(expectedClass)) {
-                return;
-            } else {
-                throw e;
-            }
-        }
-
-        throw new AssertionError("No exception thrown");
-    }
-
-    /**
-     * Return the UI device
-     *
-     * @return the UI device
-     */
-    public UiDevice getUiDevice() {
-        return sUiDevice;
-    }
-
-    protected static Instrumentation getInstrumentation() {
-        return sInstrumentation;
-    }
-
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-        sInstrumentation = InstrumentationRegistry.getInstrumentation();
-        assumeTrue(sInstrumentation.getContext().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_PRINTING));
-
-        sUiDevice = UiDevice.getInstance(sInstrumentation);
-
-        // Make sure we start with a clean slate.
-        clearPrintSpoolerData();
-
-        // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
-        // Dexmaker is used by mockito.
-        System.setProperty("dexmaker.dexcache", getInstrumentation()
-                .getTargetContext().getCacheDir().getPath());
-    }
-
-    @Before
-    public void initCounters() throws Exception {
-        // Initialize the latches.
-        mStartCallCounter = new CallCounter();
-        mStartSessionCallCounter = new CallCounter();
-    }
-
-    @Before
-    public void unlockScreen() throws Exception {
-        // Unlock screen.
-        runShellCommand(getInstrumentation(), "input keyevent KEYCODE_WAKEUP");
-        runShellCommand(getInstrumentation(), "wm dismiss-keyguard");
-    }
-
-    @After
-    public void exitActivities() throws Exception {
-        // Exit print spooler
-        getUiDevice().pressBack();
-        getUiDevice().pressBack();
-    }
-
-    protected android.print.PrintJob print(@NonNull final PrintDocumentAdapter adapter,
-            final PrintAttributes attributes) {
-        // Initiate printing as if coming from the app.
-        getInstrumentation().runOnMainSync(() -> {
-            PrintManager printManager = (PrintManager) getActivity()
-                    .getSystemService(Context.PRINT_SERVICE);
-            mPrintJob = printManager.print("Print job", adapter, attributes);
-        });
-
-        return mPrintJob;
-    }
-
-    protected void onStartCalled() {
-        mStartCallCounter.call();
-    }
-
-    protected void onPrinterDiscoverySessionStartCalled() {
-        mStartSessionCallCounter.call();
-    }
-
-    protected void waitForPrinterDiscoverySessionStartCallbackCalled() {
-        waitForCallbackCallCount(mStartSessionCallCounter, 1,
-                "Did not get expected call to onStartPrinterDiscoverySession.");
-    }
-
-    protected void waitForStartAdapterCallbackCalled() {
-        waitForCallbackCallCount(mStartCallCounter, 1, "Did not get expected call to start.");
-    }
-
-    private static void waitForCallbackCallCount(CallCounter counter, int count, String message) {
-        try {
-            counter.waitForCount(count, OPERATION_TIMEOUT);
-        } catch (TimeoutException te) {
-            fail(message);
-        }
-    }
-
-    protected PrintTestActivity getActivity() {
-        return mActivityRule.getActivity();
-    }
-
-    public static String runShellCommand(Instrumentation instrumentation, String cmd)
-            throws IOException {
-        ParcelFileDescriptor pfd = instrumentation.getUiAutomation().executeShellCommand(cmd);
-        byte[] buf = new byte[512];
-        int bytesRead;
-        FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
-        StringBuilder stdout = new StringBuilder();
-        while ((bytesRead = fis.read(buf)) != -1) {
-            stdout.append(new String(buf, 0, bytesRead));
-        }
-        fis.close();
-        return stdout.toString();
-    }
-
-    protected static void clearPrintSpoolerData() throws Exception {
-        assertTrue("failed to clear print spooler data",
-                runShellCommand(getInstrumentation(), String.format(
-                        "pm clear --user %d %s", CURRENT_USER_ID,
-                        PrintManager.PRINT_SPOOLER_PACKAGE_NAME))
-                        .contains(PM_CLEAR_SUCCESS_OUTPUT));
-    }
-
-    @SuppressWarnings("unchecked")
-    protected PrinterDiscoverySessionCallbacks createMockPrinterDiscoverySessionCallbacks(
-            Answer<Void> onStartPrinterDiscovery, Answer<Void> onStopPrinterDiscovery,
-            Answer<Void> onValidatePrinters, Answer<Void> onStartPrinterStateTracking,
-            Answer<Void> onRequestCustomPrinterIcon, Answer<Void> onStopPrinterStateTracking,
-            Answer<Void> onDestroy) {
-        PrinterDiscoverySessionCallbacks callbacks = mock(PrinterDiscoverySessionCallbacks.class);
-
-        doCallRealMethod().when(callbacks).setSession(any(StubbablePrinterDiscoverySession.class));
-        when(callbacks.getSession()).thenCallRealMethod();
-
-        if (onStartPrinterDiscovery != null) {
-            doAnswer(onStartPrinterDiscovery).when(callbacks).onStartPrinterDiscovery(
-                    any(List.class));
-        }
-        if (onStopPrinterDiscovery != null) {
-            doAnswer(onStopPrinterDiscovery).when(callbacks).onStopPrinterDiscovery();
-        }
-        if (onValidatePrinters != null) {
-            doAnswer(onValidatePrinters).when(callbacks).onValidatePrinters(
-                    any(List.class));
-        }
-        if (onStartPrinterStateTracking != null) {
-            doAnswer(onStartPrinterStateTracking).when(callbacks).onStartPrinterStateTracking(
-                    any(PrinterId.class));
-        }
-        if (onRequestCustomPrinterIcon != null) {
-            doAnswer(onRequestCustomPrinterIcon).when(callbacks).onRequestCustomPrinterIcon(
-                    any(PrinterId.class), any(CancellationSignal.class),
-                    any(CustomPrinterIconCallback.class));
-        }
-        if (onStopPrinterStateTracking != null) {
-            doAnswer(onStopPrinterStateTracking).when(callbacks).onStopPrinterStateTracking(
-                    any(PrinterId.class));
-        }
-        if (onDestroy != null) {
-            doAnswer(onDestroy).when(callbacks).onDestroy();
-        }
-
-        return callbacks;
-    }
-
-    protected PrintServiceCallbacks createMockPrintServiceCallbacks(
-            Answer<PrinterDiscoverySessionCallbacks> onCreatePrinterDiscoverySessionCallbacks,
-            Answer<Void> onPrintJobQueued, Answer<Void> onRequestCancelPrintJob) {
-        final PrintServiceCallbacks service = mock(PrintServiceCallbacks.class);
-
-        doCallRealMethod().when(service).setService(any(PrintService.class));
-        when(service.getService()).thenCallRealMethod();
-
-        if (onCreatePrinterDiscoverySessionCallbacks != null) {
-            doAnswer(onCreatePrinterDiscoverySessionCallbacks).when(service)
-                    .onCreatePrinterDiscoverySessionCallbacks();
-        }
-        if (onPrintJobQueued != null) {
-            doAnswer(onPrintJobQueued).when(service).onPrintJobQueued(any(PrintJob.class));
-        }
-        if (onRequestCancelPrintJob != null) {
-            doAnswer(onRequestCancelPrintJob).when(service).onRequestCancelPrintJob(
-                    any(PrintJob.class));
-        }
-
-        return service;
-    }
-
-    private static final class CallCounter {
-        private final Object mLock = new Object();
-
-        private int mCallCount;
-
-        public void call() {
-            synchronized (mLock) {
-                mCallCount++;
-                mLock.notifyAll();
-            }
-        }
-
-        int getCallCount() {
-            synchronized (mLock) {
-                return mCallCount;
-            }
-        }
-
-        public void waitForCount(int count, long timeoutMillis) throws TimeoutException {
-            synchronized (mLock) {
-                final long startTimeMillis = SystemClock.uptimeMillis();
-                while (mCallCount < count) {
-                    try {
-                        final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                        final long remainingTimeMillis = timeoutMillis - elapsedTimeMillis;
-                        if (remainingTimeMillis <= 0) {
-                            throw new TimeoutException();
-                        }
-                        mLock.wait(timeoutMillis);
-                    } catch (InterruptedException ie) {
-                        /* ignore */
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java
index 45e3f67..5d12f7e 100644
--- a/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java
+++ b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java
@@ -16,6 +16,8 @@
 
 package android.print;
 
+import static android.print.test.Utils.assertException;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -33,10 +35,11 @@
 import android.print.PrintAttributes.Margins;
 import android.print.PrintAttributes.MediaSize;
 import android.print.PrintAttributes.Resolution;
-import android.print.mockservice.MockPrintService;
-import android.print.mockservice.PrintServiceCallbacks;
-import android.print.mockservice.PrinterDiscoverySessionCallbacks;
-import android.print.mockservice.StubbablePrinterDiscoverySession;
+import android.print.test.BasePrintTest;
+import android.print.test.services.FirstPrintService;
+import android.print.test.services.PrintServiceCallbacks;
+import android.print.test.services.PrinterDiscoverySessionCallbacks;
+import android.print.test.services.StubbablePrinterDiscoverySession;
 import android.printservice.recommendation.IRecommendationsChangeListener;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
@@ -149,7 +152,7 @@
 
                         session.addPrinters(printers);
                     }
-                    onPrinterDiscoverySessionStartCalled();
+                    onPrinterDiscoverySessionCreateCalled();
                     return null;
                 }, null, null, null, null, null, null),
                 null, null);
@@ -200,13 +203,18 @@
     }
 
     private void startPrinting() {
-        mGoodPrintJob = print(createMockAdapter(), null);
+        mGoodPrintJob = print(createMockAdapter(), (PrintAttributes) null);
 
         // Wait for PrintActivity to be ready
-        waitForStartAdapterCallbackCalled();
+        waitForAdapterStartCallbackCalled();
 
         // Wait for printer discovery session to be ready
-        waitForPrinterDiscoverySessionStartCallbackCalled();
+        waitForPrinterDiscoverySessionCreateCallbackCalled();
+    }
+
+    private void endPrinting() {
+        getUiDevice().pressBack();
+        getUiDevice().pressBack();
     }
 
     /**
@@ -220,7 +228,7 @@
 
     @Before
     public void setUpMockService() throws Exception {
-        MockPrintService.setCallbacks(createMockCallbacks());
+        FirstPrintService.setCallbacks(createMockCallbacks());
 
         mIPrintManager = IPrintManager.Stub
                 .asInterface(ServiceManager.getService(Context.PRINT_SERVICE));
@@ -231,7 +239,7 @@
      */
     @LargeTest
     @Test
-    public void testGetPrintJobInfo() throws Exception {
+    public void testGetPrintJobInfo() throws Throwable {
         startPrinting();
 
         assertEquals(mGoodPrintJob.getId(), mIPrintManager.getPrintJobInfo(mGoodPrintJob.getId(),
@@ -244,6 +252,8 @@
                 SecurityException.class);
 
         // Cannot test bad user Id as these tests are allowed to call across users
+
+        endPrinting();
     }
 
     /**
@@ -251,7 +261,7 @@
      */
     @LargeTest
     @Test
-    public void testGetPrintJobInfos() throws Exception {
+    public void testGetPrintJobInfos() throws Throwable {
         startPrinting();
 
         List<PrintJobInfo> infos = mIPrintManager.getPrintJobInfos(mAppId, mUserId);
@@ -269,6 +279,8 @@
                 SecurityException.class);
 
         // Cannot test bad user Id as these tests are allowed to call across users
+
+        endPrinting();
     }
 
     /**
@@ -276,7 +288,7 @@
      */
     @LargeTest
     @Test
-    public void testPrint() throws Exception {
+    public void testPrint() throws Throwable {
         final String name = "dummy print job";
 
         final IPrintDocumentAdapter adapter = new PrintManager
@@ -303,6 +315,8 @@
                 getActivity().getPackageName(), BAD_APP_ID, mUserId), SecurityException.class);
 
         // Cannot test bad user Id as these tests are allowed to call across users
+
+        endPrinting();
     }
 
     /**
@@ -310,7 +324,7 @@
      */
     @LargeTest
     @Test
-    public void testCancelPrintJob() throws Exception {
+    public void testCancelPrintJob() throws Throwable {
         startPrinting();
 
         // Invalid print jobs IDs do not produce an exception
@@ -325,6 +339,8 @@
 
         // Must be last as otherwise mGoodPrintJob will not be good anymore
         mIPrintManager.cancelPrintJob(mGoodPrintJob.getId(), mAppId, mUserId);
+
+        endPrinting();
     }
 
     /**
@@ -332,7 +348,7 @@
      */
     @LargeTest
     @Test
-    public void testRestartPrintJob() throws Exception {
+    public void testRestartPrintJob() throws Throwable {
         startPrinting();
 
         mIPrintManager.restartPrintJob(mGoodPrintJob.getId(), mAppId, mUserId);
@@ -346,6 +362,8 @@
                 SecurityException.class);
 
         // Cannot test bad user Id as these tests are allowed to call across users
+
+        endPrinting();
     }
 
     /**
@@ -353,7 +371,8 @@
      */
     @MediumTest
     @Test
-    public void testAddPrintJobStateChangeListener() throws Exception {
+    @NoActivity
+    public void testAddPrintJobStateChangeListener() throws Throwable {
         final IPrintJobStateChangeListener listener = createMockIPrintJobStateChangeListener();
 
         mIPrintManager.addPrintJobStateChangeListener(listener, mAppId, mUserId);
@@ -373,7 +392,8 @@
      */
     @MediumTest
     @Test
-    public void testRemovePrintJobStateChangeListener() throws Exception {
+    @NoActivity
+    public void testRemovePrintJobStateChangeListener() throws Throwable {
         final IPrintJobStateChangeListener listener = createMockIPrintJobStateChangeListener();
 
         mIPrintManager.addPrintJobStateChangeListener(listener, mAppId, mUserId);
@@ -394,7 +414,8 @@
      */
     @MediumTest
     @Test
-    public void testAddPrintServicesChangeListener() throws Exception {
+    @NoActivity
+    public void testAddPrintServicesChangeListener() throws Throwable {
         final IPrintServicesChangeListener listener = createMockIPrintServicesChangeListener();
 
         assertException(() ->  mIPrintManager.addPrintServicesChangeListener(listener, mUserId),
@@ -411,7 +432,8 @@
      */
     @MediumTest
     @Test
-    public void testRemovePrintServicesChangeListener() throws Exception {
+    @NoActivity
+    public void testRemovePrintServicesChangeListener() throws Throwable {
         final IPrintServicesChangeListener listener = createMockIPrintServicesChangeListener();
 
         assertException(() ->  mIPrintManager.removePrintServicesChangeListener(listener, mUserId),
@@ -426,7 +448,8 @@
      */
     @MediumTest
     @Test
-    public void testGetPrintServices() throws Exception {
+    @NoActivity
+    public void testGetPrintServices() throws Throwable {
         assertException(() -> mIPrintManager.getPrintServices(PrintManager.ALL_SERVICES, mUserId),
                 SecurityException.class);
 
@@ -444,7 +467,8 @@
      */
     @MediumTest
     @Test
-    public void testSetPrintServiceEnabled() throws Exception {
+    @NoActivity
+    public void testSetPrintServiceEnabled() throws Throwable {
         assertException(
                 () -> mIPrintManager.setPrintServiceEnabled(new ComponentName("bad", "name"), true,
                                 mUserId), SecurityException.class);
@@ -460,7 +484,8 @@
      */
     @MediumTest
     @Test
-    public void testAddPrintServiceRecommendationsChangeListener() throws Exception {
+    @NoActivity
+    public void testAddPrintServiceRecommendationsChangeListener() throws Throwable {
         final IRecommendationsChangeListener listener =
                 createMockIPrintServiceRecommendationsChangeListener();
 
@@ -479,7 +504,8 @@
      */
     @MediumTest
     @Test
-    public void testRemovePrintServiceRecommendationsChangeListener() throws Exception {
+    @NoActivity
+    public void testRemovePrintServiceRecommendationsChangeListener() throws Throwable {
         final IRecommendationsChangeListener listener =
                 createMockIPrintServiceRecommendationsChangeListener();
 
@@ -498,7 +524,8 @@
      */
     @MediumTest
     @Test
-    public void testGetPrintServiceRecommendations() throws Exception {
+    @NoActivity
+    public void testGetPrintServiceRecommendations() throws Throwable {
         assertException(() -> mIPrintManager.getPrintServiceRecommendations(mUserId),
                 SecurityException.class);
 
@@ -510,7 +537,8 @@
      */
     @MediumTest
     @Test
-    public void testCreatePrinterDiscoverySession() throws Exception {
+    @NoActivity
+    public void testCreatePrinterDiscoverySession() throws Throwable {
         final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
 
         mIPrintManager.createPrinterDiscoverySession(listener, mUserId);
@@ -533,7 +561,7 @@
      */
     @LargeTest
     @Test
-    public void testStartPrinterDiscovery() throws Exception {
+    public void testStartPrinterDiscovery() throws Throwable {
         startPrinting();
 
         final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
@@ -562,6 +590,8 @@
                 NullPointerException.class);
 
         // Cannot test bad user Id as these tests are allowed to call across users
+
+        endPrinting();
     }
 
     /**
@@ -569,7 +599,8 @@
      */
     @MediumTest
     @Test
-    public void testStopPrinterDiscovery() throws Exception {
+    @NoActivity
+    public void testStopPrinterDiscovery() throws Throwable {
         final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
 
         mIPrintManager.startPrinterDiscovery(listener, null, mUserId);
@@ -590,7 +621,7 @@
      */
     @LargeTest
     @Test
-    public void testValidatePrinters() throws Exception {
+    public void testValidatePrinters() throws Throwable {
         startPrinting();
 
         final List<PrinterId> goodPrinters = new ArrayList<>();
@@ -617,6 +648,8 @@
                 NullPointerException.class);
 
         // Cannot test bad user Id as these tests are allowed to call across users
+
+        endPrinting();
     }
 
     /**
@@ -624,7 +657,7 @@
      */
     @LargeTest
     @Test
-    public void testStartPrinterStateTracking() throws Exception {
+    public void testStartPrinterStateTracking() throws Throwable {
         startPrinting();
 
         mIPrintManager.startPrinterStateTracking(mGoodPrinterId, mUserId);
@@ -636,6 +669,8 @@
                 NullPointerException.class);
 
         // Cannot test bad user Id as these tests are allowed to call across users
+
+        endPrinting();
     }
 
     /**
@@ -643,7 +678,7 @@
      */
     @LargeTest
     @Test
-    public void testGetCustomPrinterIcon() throws Exception {
+    public void testGetCustomPrinterIcon() throws Throwable {
         startPrinting();
 
         mIPrintManager.getCustomPrinterIcon(mGoodPrinterId, mUserId);
@@ -655,6 +690,8 @@
                 NullPointerException.class);
 
         // Cannot test bad user Id as these tests are allowed to call across users
+
+        endPrinting();
     }
 
     /**
@@ -662,7 +699,7 @@
      */
     @LargeTest
     @Test
-    public void testStopPrinterStateTracking() throws Exception {
+    public void testStopPrinterStateTracking() throws Throwable {
         startPrinting();
 
         mIPrintManager.startPrinterStateTracking(mGoodPrinterId, mUserId);
@@ -679,6 +716,8 @@
                 NullPointerException.class);
 
         // Cannot test bad user Id as these tests are allowed to call across users
+
+        endPrinting();
     }
 
     /**
@@ -686,7 +725,8 @@
      */
     @MediumTest
     @Test
-    public void testDestroyPrinterDiscoverySession() throws Exception {
+    @NoActivity
+    public void testDestroyPrinterDiscoverySession() throws Throwable {
         final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
 
         mIPrintManager.createPrinterDiscoverySession(listener, mUserId);
diff --git a/core/tests/coretests/src/android/print/PrintTestActivity.java b/core/tests/coretests/src/android/print/PrintTestActivity.java
deleted file mode 100644
index e9b001f..0000000
--- a/core/tests/coretests/src/android/print/PrintTestActivity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.print;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.WindowManager;
-
-public class PrintTestActivity extends Activity {
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
-    }
-}
diff --git a/core/tests/coretests/src/android/print/mockservice/MockPrintService.java b/core/tests/coretests/src/android/print/mockservice/MockPrintService.java
deleted file mode 100644
index 9c11c22..0000000
--- a/core/tests/coretests/src/android/print/mockservice/MockPrintService.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.print.mockservice;
-
-public class MockPrintService extends StubbablePrintService {
-
-    private static final Object sLock = new Object();
-
-    private static PrintServiceCallbacks sCallbacks;
-
-    public static void setCallbacks(PrintServiceCallbacks callbacks) {
-        synchronized (sLock) {
-            sCallbacks = callbacks;
-        }
-    }
-
-    @Override
-    protected PrintServiceCallbacks getCallbacks() {
-        synchronized (sLock) {
-            if (sCallbacks != null) {
-                sCallbacks.setService(this);
-            }
-            return sCallbacks;
-        }
-    }
-}
diff --git a/core/tests/coretests/src/android/print/mockservice/PrintServiceCallbacks.java b/core/tests/coretests/src/android/print/mockservice/PrintServiceCallbacks.java
deleted file mode 100644
index 4e89207..0000000
--- a/core/tests/coretests/src/android/print/mockservice/PrintServiceCallbacks.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.print.mockservice;
-
-import android.printservice.PrintJob;
-import android.printservice.PrintService;
-
-public abstract class PrintServiceCallbacks {
-
-    private PrintService mService;
-
-    public PrintService getService() {
-        return mService;
-    }
-
-    public void setService(PrintService service) {
-        mService = service;
-    }
-
-    public abstract PrinterDiscoverySessionCallbacks onCreatePrinterDiscoverySessionCallbacks();
-
-    public abstract void onRequestCancelPrintJob(PrintJob printJob);
-
-    public abstract void onPrintJobQueued(PrintJob printJob);
-}
diff --git a/core/tests/coretests/src/android/print/mockservice/PrinterDiscoverySessionCallbacks.java b/core/tests/coretests/src/android/print/mockservice/PrinterDiscoverySessionCallbacks.java
deleted file mode 100644
index be002e2..0000000
--- a/core/tests/coretests/src/android/print/mockservice/PrinterDiscoverySessionCallbacks.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.print.mockservice;
-
-import android.os.CancellationSignal;
-import android.print.PrinterId;
-import android.printservice.CustomPrinterIconCallback;
-
-import java.util.List;
-
-public abstract class PrinterDiscoverySessionCallbacks {
-
-    private StubbablePrinterDiscoverySession mSession;
-
-    public void setSession(StubbablePrinterDiscoverySession session) {
-        mSession = session;
-    }
-
-    public StubbablePrinterDiscoverySession getSession() {
-        return mSession;
-    }
-
-    public abstract void onStartPrinterDiscovery(List<PrinterId> priorityList);
-
-    public abstract void onStopPrinterDiscovery();
-
-    public abstract void onValidatePrinters(List<PrinterId> printerIds);
-
-    public abstract void onStartPrinterStateTracking(PrinterId printerId);
-
-    public abstract void onRequestCustomPrinterIcon(PrinterId printerId,
-            CancellationSignal cancellationSignal, CustomPrinterIconCallback callback);
-
-    public abstract void onStopPrinterStateTracking(PrinterId printerId);
-
-    public abstract void onDestroy();
-}
diff --git a/core/tests/coretests/src/android/print/mockservice/StubbablePrintService.java b/core/tests/coretests/src/android/print/mockservice/StubbablePrintService.java
deleted file mode 100644
index b58b2735..0000000
--- a/core/tests/coretests/src/android/print/mockservice/StubbablePrintService.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.print.mockservice;
-
-import android.printservice.PrintJob;
-import android.printservice.PrintService;
-import android.printservice.PrinterDiscoverySession;
-
-public abstract class StubbablePrintService extends PrintService {
-
-    @Override
-    public PrinterDiscoverySession onCreatePrinterDiscoverySession() {
-        PrintServiceCallbacks callbacks = getCallbacks();
-        if (callbacks != null) {
-            return new StubbablePrinterDiscoverySession(this,
-                    getCallbacks().onCreatePrinterDiscoverySessionCallbacks());
-        }
-        return null;
-    }
-
-    @Override
-    public void onRequestCancelPrintJob(PrintJob printJob) {
-        PrintServiceCallbacks callbacks = getCallbacks();
-        if (callbacks != null) {
-            callbacks.onRequestCancelPrintJob(printJob);
-        }
-    }
-
-    @Override
-    public void onPrintJobQueued(PrintJob printJob) {
-        PrintServiceCallbacks callbacks = getCallbacks();
-        if (callbacks != null) {
-            callbacks.onPrintJobQueued(printJob);
-        }
-    }
-
-    protected abstract PrintServiceCallbacks getCallbacks();
-}
diff --git a/core/tests/coretests/src/android/print/mockservice/StubbablePrinterDiscoverySession.java b/core/tests/coretests/src/android/print/mockservice/StubbablePrinterDiscoverySession.java
deleted file mode 100644
index f3a5373..0000000
--- a/core/tests/coretests/src/android/print/mockservice/StubbablePrinterDiscoverySession.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.print.mockservice;
-
-import android.support.annotation.NonNull;
-import android.os.CancellationSignal;
-import android.print.PrinterId;
-import android.printservice.CustomPrinterIconCallback;
-import android.printservice.PrintService;
-import android.printservice.PrinterDiscoverySession;
-
-import java.util.List;
-
-public class StubbablePrinterDiscoverySession extends PrinterDiscoverySession {
-    private final PrintService mService;
-    private final PrinterDiscoverySessionCallbacks mCallbacks;
-
-    public StubbablePrinterDiscoverySession(PrintService service,
-            PrinterDiscoverySessionCallbacks callbacks) {
-        mService = service;
-        mCallbacks = callbacks;
-        if (mCallbacks != null) {
-            mCallbacks.setSession(this);
-        }
-    }
-
-    public PrintService getService() {
-        return mService;
-    }
-
-    @Override
-    public void onStartPrinterDiscovery(@NonNull List<PrinterId> priorityList) {
-        if (mCallbacks != null) {
-            mCallbacks.onStartPrinterDiscovery(priorityList);
-        }
-    }
-
-    @Override
-    public void onStopPrinterDiscovery() {
-        if (mCallbacks != null) {
-            mCallbacks.onStopPrinterDiscovery();
-        }
-    }
-
-    @Override
-    public void onValidatePrinters(@NonNull List<PrinterId> printerIds) {
-        if (mCallbacks != null) {
-            mCallbacks.onValidatePrinters(printerIds);
-        }
-    }
-
-    @Override
-    public void onStartPrinterStateTracking(@NonNull PrinterId printerId) {
-        if (mCallbacks != null) {
-            mCallbacks.onStartPrinterStateTracking(printerId);
-        }
-    }
-
-    @Override
-    public void onRequestCustomPrinterIcon(@NonNull PrinterId printerId,
-            @NonNull CancellationSignal cancellationSignal,
-            @NonNull CustomPrinterIconCallback callback) {
-        if (mCallbacks != null) {
-            mCallbacks.onRequestCustomPrinterIcon(printerId, cancellationSignal, callback);
-        }
-    }
-
-    @Override
-    public void onStopPrinterStateTracking(@NonNull PrinterId printerId) {
-        if (mCallbacks != null) {
-            mCallbacks.onStopPrinterStateTracking(printerId);
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mCallbacks != null) {
-            mCallbacks.onDestroy();
-        }
-    }
-}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 6731536..6c32590 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -342,6 +342,7 @@
                     Settings.Global.TETHER_DUN_REQUIRED,
                     Settings.Global.TETHER_OFFLOAD_DISABLED,
                     Settings.Global.TETHER_SUPPORTED,
+                    Settings.Global.TEXT_CLASSIFIER_CONSTANTS,
                     Settings.Global.THEATER_MODE_ON,
                     Settings.Global.TRANSITION_ANIMATION_SCALE,
                     Settings.Global.TRUSTED_SOUND,
@@ -463,7 +464,6 @@
                  Settings.Secure.NFC_PAYMENT_FOREGROUND,
                  Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
                  Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
-                 Settings.Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME,
                  Settings.Secure.PACKAGE_VERIFIER_STATE,
                  Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT,
                  Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index 461d537..4e83221 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -214,7 +214,7 @@
         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
     }
 
-    /** Test BatteryStatsImpl.noteScreenStateLocked. */
+    /** Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly. */
     @SmallTest
     public void testNoteScreenStateLocked() throws Exception {
         final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
@@ -233,4 +233,52 @@
         assertEquals(bi.getScreenState(), Display.STATE_OFF);
     }
 
+    /** Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly.
+     *
+     *  Unknown and doze should both be subset of off state
+     *
+     *  Timeline 0----100----200----310----400------------1000
+     *  Unknown         -------
+     *  On                     -------
+     *  Off             -------       ----------------------
+     *  Doze                                ----------------
+     */
+    @SmallTest
+    public void testNoteScreenStateTimersLocked() throws Exception {
+        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+
+        clocks.realtime = clocks.uptime = 100;
+        // Device startup, setOnBatteryLocked calls updateTimebases
+        bi.updateTimeBasesLocked(true, Display.STATE_UNKNOWN, 100_000, 100_000);
+        // Turn on display at 200us
+        clocks.realtime = clocks.uptime = 200;
+        bi.noteScreenStateLocked(Display.STATE_ON);
+        assertEquals(150_000, bi.computeBatteryRealtime(250_000, STATS_SINCE_CHARGED));
+        assertEquals(100_000, bi.computeBatteryScreenOffRealtime(250_000, STATS_SINCE_CHARGED));
+        assertEquals(50_000, bi.getScreenOnTime(250_000, STATS_SINCE_CHARGED));
+        assertEquals(0, bi.getScreenDozeTime(250_000, STATS_SINCE_CHARGED));
+
+        clocks.realtime = clocks.uptime = 310;
+        bi.noteScreenStateLocked(Display.STATE_OFF);
+        assertEquals(250_000, bi.computeBatteryRealtime(350_000, STATS_SINCE_CHARGED));
+        assertEquals(140_000, bi.computeBatteryScreenOffRealtime(350_000, STATS_SINCE_CHARGED));
+        assertEquals(110_000, bi.getScreenOnTime(350_000, STATS_SINCE_CHARGED));
+        assertEquals(0, bi.getScreenDozeTime(350_000, STATS_SINCE_CHARGED));
+
+        clocks.realtime = clocks.uptime = 400;
+        bi.noteScreenStateLocked(Display.STATE_DOZE);
+        assertEquals(400_000, bi.computeBatteryRealtime(500_000, STATS_SINCE_CHARGED));
+        assertEquals(290_000, bi.computeBatteryScreenOffRealtime(500_000, STATS_SINCE_CHARGED));
+        assertEquals(110_000, bi.getScreenOnTime(500_000, STATS_SINCE_CHARGED));
+        assertEquals(100_000, bi.getScreenDozeTime(500_000, STATS_SINCE_CHARGED));
+
+        clocks.realtime = clocks.uptime = 1000;
+        bi.noteScreenStateLocked(Display.STATE_OFF);
+        assertEquals(1400_000, bi.computeBatteryRealtime(1500_000, STATS_SINCE_CHARGED));
+        assertEquals(1290_000, bi.computeBatteryScreenOffRealtime(1500_000, STATS_SINCE_CHARGED));
+        assertEquals(110_000, bi.getScreenOnTime(1500_000, STATS_SINCE_CHARGED));
+        assertEquals(600_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED));
+    }
+
 }
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 6a3a973..902b872 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -253,12 +253,14 @@
     </privapp-permissions>
 
     <privapp-permissions package="com.android.shell">
+        <permission name="android.permission.ACCESS_LOWPAN_STATE"/>
         <permission name="android.permission.BACKUP"/>
         <permission name="android.permission.BATTERY_STATS"/>
         <permission name="android.permission.BIND_APPWIDGET"/>
         <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
         <permission name="android.permission.CHANGE_CONFIGURATION"/>
         <permission name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST" />
+        <permission name="android.permission.CHANGE_LOWPAN_STATE"/>
         <permission name="android.permission.CHANGE_OVERLAY_PACKAGES"/>
         <permission name="android.permission.CLEAR_APP_CACHE"/>
         <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
@@ -282,6 +284,7 @@
         <permission name="android.permission.MOVE_PACKAGE"/>
         <permission name="android.permission.PACKAGE_USAGE_STATS" />
         <permission name="android.permission.READ_FRAME_BUFFER"/>
+        <permission name="android.permission.READ_LOWPAN_CREDENTIAL"/>
         <permission name="android.permission.REAL_GET_TASKS"/>
         <permission name="android.permission.REGISTER_CALL_PROVIDER"/>
         <permission name="android.permission.REGISTER_CONNECTION_MANAGER"/>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 57c7549..0072012 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.Size;
+import android.annotation.WorkerThread;
 import android.content.res.ResourcesImpl;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -1233,6 +1234,7 @@
      * @param stream   The outputstream to write the compressed data.
      * @return true if successfully compressed to the specified stream.
      */
+    @WorkerThread
     public boolean compress(CompressFormat format, int quality, OutputStream stream) {
         checkRecycled("Can't compress a recycled bitmap");
         // do explicit check before calling the native method
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index ffb39e3..f5bf754 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -354,6 +354,7 @@
          * decode, in the case of which a more accurate, but slightly slower,
          * IDCT method will be used instead.
          */
+        @Deprecated
         public boolean inPreferQualityOverSpeed;
 
         /**
@@ -412,6 +413,7 @@
          * can check, inbetween the bounds decode and the image decode, to see
          * if the operation is canceled.
          */
+        @Deprecated
         public boolean mCancel;
 
         /**
@@ -426,6 +428,7 @@
          *  or if inJustDecodeBounds is true, will set outWidth/outHeight
          *  to -1
          */
+        @Deprecated
         public void requestCancelDecode() {
             mCancel = true;
         }
diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java
index ed417b9..a675eaf 100644
--- a/graphics/java/android/graphics/drawable/RippleForeground.java
+++ b/graphics/java/android/graphics/drawable/RippleForeground.java
@@ -169,13 +169,13 @@
         final ObjectAnimator tweenRadius = ObjectAnimator.ofFloat(this, TWEEN_RADIUS, 1);
         tweenRadius.setAutoCancel(true);
         tweenRadius.setDuration(duration);
-        tweenRadius.setInterpolator(LINEAR_INTERPOLATOR);
+        tweenRadius.setInterpolator(DECELERATE_INTERPOLATOR);
         tweenRadius.setStartDelay(RIPPLE_ENTER_DELAY);
 
         final ObjectAnimator tweenOrigin = ObjectAnimator.ofFloat(this, TWEEN_ORIGIN, 1);
         tweenOrigin.setAutoCancel(true);
         tweenOrigin.setDuration(duration);
-        tweenOrigin.setInterpolator(LINEAR_INTERPOLATOR);
+        tweenOrigin.setInterpolator(DECELERATE_INTERPOLATOR);
         tweenOrigin.setStartDelay(RIPPLE_ENTER_DELAY);
 
         final ObjectAnimator opacity = ObjectAnimator.ofFloat(this, OPACITY, 1);
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index c4c14c9e..5484cf0 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -14,15 +14,27 @@
 
 // libandroidfw is partially built for the host (used by obbtool, aapt, and others)
 
-cc_library {
-    name: "libandroidfw",
-    host_supported: true,
+cc_defaults {
+    name: "libandroidfw_defaults",
     cflags: [
-        "-Wall",
         "-Werror",
-        "-Wunused",
         "-Wunreachable-code",
     ],
+    target: {
+        windows: {
+            // The Windows compiler warns incorrectly for value initialization with {}.
+            cppflags: ["-Wno-missing-field-initializers"],
+        },
+        host: {
+            cflags: ["-DSTATIC_ANDROIDFW_FOR_TOOLS"],
+        },
+    },
+}
+
+cc_library {
+    name: "libandroidfw",
+    defaults: ["libandroidfw_defaults"],
+    host_supported: true,
     srcs: [
         "ApkAssets.cpp",
         "Asset.cpp",
@@ -31,6 +43,7 @@
         "AssetManager2.cpp",
         "AttributeResolution.cpp",
         "ChunkIterator.cpp",
+        "Idmap.cpp",
         "LoadedArsc.cpp",
         "LocaleData.cpp",
         "misc.cpp",
@@ -67,7 +80,6 @@
             },
         },
         host: {
-            cflags: ["-DSTATIC_ANDROIDFW_FOR_TOOLS"],
             shared: {
                 enabled: false,
             },
@@ -84,9 +96,82 @@
         },
         windows: {
             enabled: true,
-            cppflags: ["-Wno-missing-field-initializers"],  // The Windows compiler warns
-                                                            // incorrectly for value
-                                                            // initialization with {}.
         },
     },
 }
+
+common_test_libs = [
+    "libandroidfw",
+    "libbase",
+    "libcutils",
+    "libutils",
+    "libziparchive",
+]
+
+cc_test {
+    name: "libandroidfw_tests",
+    host_supported: true,
+    defaults: ["libandroidfw_defaults"],
+    cppflags: [
+        // This is to suppress warnings/errors from gtest
+        "-Wno-unnamed-type-template-args",
+    ],
+    srcs: [
+        // Helpers/infra for testing.
+        "tests/CommonHelpers.cpp",
+        "tests/TestHelpers.cpp",
+        "tests/TestMain.cpp",
+
+        // Actual tests.
+        "tests/ApkAssets_test.cpp",
+        "tests/AppAsLib_test.cpp",
+        "tests/Asset_test.cpp",
+        "tests/AssetManager2_test.cpp",
+        "tests/AttributeFinder_test.cpp",
+        "tests/AttributeResolution_test.cpp",
+        "tests/ByteBucketArray_test.cpp",
+        "tests/Config_test.cpp",
+        "tests/ConfigLocale_test.cpp",
+        "tests/Idmap_test.cpp",
+        "tests/LoadedArsc_test.cpp",
+        "tests/ResourceUtils_test.cpp",
+        "tests/ResTable_test.cpp",
+        "tests/Split_test.cpp",
+        "tests/StringPiece_test.cpp",
+        "tests/Theme_test.cpp",
+        "tests/TypeWrappers_test.cpp",
+        "tests/ZipUtils_test.cpp",
+    ],
+    target: {
+        android: {
+            srcs: [
+                "tests/BackupData_test.cpp",
+                "tests/ObbFile_test.cpp",
+            ],
+            shared_libs: common_test_libs + ["libui"],
+        },
+        host: {
+            static_libs: common_test_libs + ["liblog", "libz"],
+        },
+    },
+    data: ["tests/data/**/*.apk"],
+}
+
+cc_benchmark {
+    name: "libandroidfw_benchmarks",
+    defaults: ["libandroidfw_defaults"],
+    srcs: [
+        // Helpers/infra for benchmarking.
+        "tests/BenchMain.cpp",
+        "tests/BenchmarkHelpers.cpp",
+        "tests/CommonHelpers.cpp",
+
+        // Actual benchmarks.
+        "tests/AssetManager2_bench.cpp",
+        "tests/SparseEntry_bench.cpp",
+        "tests/Theme_bench.cpp",
+    ],
+    shared_libs: common_test_libs,
+    data: ["tests/data/**/*.apk"],
+}
+
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
deleted file mode 100644
index 68c51ef..0000000
--- a/libs/androidfw/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2010 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Include subdirectory makefiles
-# ============================================================
-
-# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
-# team really wants is to build the stuff defined by this makefile.
-ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call first-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 0e577d1..158df13 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -20,64 +20,126 @@
 
 #include <algorithm>
 
+#include "android-base/errors.h"
+#include "android-base/file.h"
 #include "android-base/logging.h"
+#include "android-base/unique_fd.h"
+#include "android-base/utf8.h"
+#include "utils/Compat.h"
 #include "utils/FileMap.h"
 #include "utils/Trace.h"
 #include "ziparchive/zip_archive.h"
 
 #include "androidfw/Asset.h"
+#include "androidfw/Idmap.h"
+#include "androidfw/ResourceTypes.h"
 #include "androidfw/Util.h"
 
 namespace android {
 
-ApkAssets::ApkAssets() : zip_handle_(nullptr, ::CloseArchive) {}
+using base::SystemErrorCodeToString;
+using base::unique_fd;
+
+static const std::string kResourcesArsc("resources.arsc");
+
+ApkAssets::ApkAssets(void* unmanaged_handle, const std::string& path)
+    : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path) {
+}
 
 std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) {
-  return ApkAssets::LoadImpl(path, system, false /*load_as_shared_library*/);
+  return ApkAssets::LoadImpl(path, nullptr, nullptr, system, false /*load_as_shared_library*/);
 }
 
 std::unique_ptr<const ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path,
                                                                 bool system) {
-  return ApkAssets::LoadImpl(path, system, true /*load_as_shared_library*/);
+  return ApkAssets::LoadImpl(path, nullptr, nullptr, system, true /*load_as_shared_library*/);
 }
 
-std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(const std::string& path, bool system,
-                                                     bool load_as_shared_library) {
+std::unique_ptr<const ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap_path,
+                                                        bool system) {
+  std::unique_ptr<Asset> idmap_asset = CreateAssetFromFile(idmap_path);
+  if (idmap_asset == nullptr) {
+    return {};
+  }
+
+  const StringPiece idmap_data(
+      reinterpret_cast<const char*>(idmap_asset->getBuffer(true /*wordAligned*/)),
+      static_cast<size_t>(idmap_asset->getLength()));
+  std::unique_ptr<const LoadedIdmap> loaded_idmap = LoadedIdmap::Load(idmap_data);
+  if (loaded_idmap == nullptr) {
+    LOG(ERROR) << "failed to load IDMAP " << idmap_path;
+    return {};
+  }
+  return LoadImpl(loaded_idmap->OverlayApkPath(), std::move(idmap_asset), std::move(loaded_idmap),
+                  system, false /*load_as_shared_library*/);
+}
+
+std::unique_ptr<Asset> ApkAssets::CreateAssetFromFile(const std::string& path) {
+  unique_fd fd(base::utf8::open(path.c_str(), O_RDONLY | O_BINARY | O_CLOEXEC));
+  if (fd == -1) {
+    LOG(ERROR) << "Failed to open file '" << path << "': " << SystemErrorCodeToString(errno);
+    return {};
+  }
+
+  const off64_t file_len = lseek64(fd, 0, SEEK_END);
+  if (file_len < 0) {
+    LOG(ERROR) << "Failed to get size of file '" << path << "': " << SystemErrorCodeToString(errno);
+    return {};
+  }
+
+  std::unique_ptr<FileMap> file_map = util::make_unique<FileMap>();
+  if (!file_map->create(path.c_str(), fd, 0, static_cast<size_t>(file_len), true /*readOnly*/)) {
+    LOG(ERROR) << "Failed to mmap file '" << path << "': " << SystemErrorCodeToString(errno);
+    return {};
+  }
+  return Asset::createFromUncompressedMap(std::move(file_map), Asset::AccessMode::ACCESS_RANDOM);
+}
+
+std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
+    const std::string& path, std::unique_ptr<Asset> idmap_asset,
+    std::unique_ptr<const LoadedIdmap> loaded_idmap, bool system, bool load_as_shared_library) {
   ATRACE_CALL();
   ::ZipArchiveHandle unmanaged_handle;
   int32_t result = ::OpenArchive(path.c_str(), &unmanaged_handle);
   if (result != 0) {
-    LOG(ERROR) << ::ErrorCodeString(result);
+    LOG(ERROR) << "Failed to open APK '" << path << "' " << ::ErrorCodeString(result);
     return {};
   }
 
   // Wrap the handle in a unique_ptr so it gets automatically closed.
-  std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets());
-  loaded_apk->zip_handle_.reset(unmanaged_handle);
+  std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(unmanaged_handle, path));
 
-  ::ZipString entry_name("resources.arsc");
+  // Find the resource table.
+  ::ZipString entry_name(kResourcesArsc.c_str());
   ::ZipEntry entry;
   result = ::FindEntry(loaded_apk->zip_handle_.get(), entry_name, &entry);
   if (result != 0) {
-    LOG(ERROR) << ::ErrorCodeString(result);
-    return {};
+    // There is no resources.arsc, so create an empty LoadedArsc and return.
+    loaded_apk->loaded_arsc_ = LoadedArsc::CreateEmpty();
+    return std::move(loaded_apk);
   }
 
   if (entry.method == kCompressDeflated) {
-    LOG(WARNING) << "resources.arsc is compressed.";
+    LOG(WARNING) << kResourcesArsc << " in APK '" << path << "' is compressed.";
   }
 
-  loaded_apk->path_ = path;
-  loaded_apk->resources_asset_ =
-      loaded_apk->Open("resources.arsc", Asset::AccessMode::ACCESS_BUFFER);
+  // Open the resource table via mmap unless it is compressed. This logic is taken care of by Open.
+  loaded_apk->resources_asset_ = loaded_apk->Open(kResourcesArsc, Asset::AccessMode::ACCESS_BUFFER);
   if (loaded_apk->resources_asset_ == nullptr) {
+    LOG(ERROR) << "Failed to open '" << kResourcesArsc << "' in APK '" << path << "'.";
     return {};
   }
 
+  // Must retain ownership of the IDMAP Asset so that all pointers to its mmapped data remain valid.
+  loaded_apk->idmap_asset_ = std::move(idmap_asset);
+
+  const StringPiece data(
+      reinterpret_cast<const char*>(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/)),
+      loaded_apk->resources_asset_->getLength());
   loaded_apk->loaded_arsc_ =
-      LoadedArsc::Load(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/),
-                       loaded_apk->resources_asset_->getLength(), system, load_as_shared_library);
+      LoadedArsc::Load(data, loaded_idmap.get(), system, load_as_shared_library);
   if (loaded_apk->loaded_arsc_ == nullptr) {
+    LOG(ERROR) << "Failed to load '" << kResourcesArsc << "' in APK '" << path << "'.";
     return {};
   }
 
@@ -93,7 +155,6 @@
   ::ZipEntry entry;
   int32_t result = ::FindEntry(zip_handle_.get(), name, &entry);
   if (result != 0) {
-    LOG(ERROR) << "No entry '" << path << "' found in APK '" << path_ << "'";
     return {};
   }
 
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index f1f2e2d..d4d9dcb 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -35,7 +35,9 @@
 
 namespace android {
 
-AssetManager2::AssetManager2() { memset(&configuration_, 0, sizeof(configuration_)); }
+AssetManager2::AssetManager2() {
+  memset(&configuration_, 0, sizeof(configuration_));
+}
 
 bool AssetManager2::SetApkAssets(const std::vector<const ApkAssets*>& apk_assets,
                                  bool invalidate_caches) {
@@ -55,9 +57,9 @@
   int next_package_id = 0x02;
   const size_t apk_assets_count = apk_assets_.size();
   for (size_t i = 0; i < apk_assets_count; i++) {
-    const ApkAssets* apk_asset = apk_assets_[i];
-    for (const std::unique_ptr<const LoadedPackage>& package :
-         apk_asset->GetLoadedArsc()->GetPackages()) {
+    const LoadedArsc* loaded_arsc = apk_assets_[i]->GetLoadedArsc();
+
+    for (const std::unique_ptr<const LoadedPackage>& package : loaded_arsc->GetPackages()) {
       // Get the package ID or assign one if a shared library.
       int package_id;
       if (package->IsDynamic()) {
@@ -312,7 +314,8 @@
 
     cumulated_flags |= current_flags;
 
-    if (best_cookie == kInvalidCookie || current_config.isBetterThan(best_config, desired_config)) {
+    if (best_cookie == kInvalidCookie || current_config.isBetterThan(best_config, desired_config) ||
+        (loaded_package->IsOverlay() && current_config.compare(best_config) == 0)) {
       best_entry = current_entry;
       best_config = current_config;
       best_cookie = package_group.cookies_[i];
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
new file mode 100644
index 0000000..7c1ee5c
--- /dev/null
+++ b/libs/androidfw/Idmap.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define ATRACE_TAG ATRACE_TAG_RESOURCES
+
+#include "androidfw/Idmap.h"
+
+#include "android-base/logging.h"
+#include "android-base/stringprintf.h"
+#include "utils/ByteOrder.h"
+#include "utils/Trace.h"
+
+#ifdef _WIN32
+#ifdef ERROR
+#undef ERROR
+#endif
+#endif
+
+#include "androidfw/ResourceTypes.h"
+
+using ::android::base::StringPrintf;
+
+namespace android {
+
+constexpr static inline bool is_valid_package_id(uint16_t id) {
+  return id != 0 && id <= 255;
+}
+
+constexpr static inline bool is_valid_type_id(uint16_t id) {
+  // Type IDs and package IDs have the same constraints in the IDMAP.
+  return is_valid_package_id(id);
+}
+
+bool LoadedIdmap::Lookup(const IdmapEntry_header* header, uint16_t input_entry_id,
+                         uint16_t* output_entry_id) {
+  if (input_entry_id < dtohs(header->entry_id_offset)) {
+    // After applying the offset, the entry is not present.
+    return false;
+  }
+
+  input_entry_id -= dtohs(header->entry_id_offset);
+  if (input_entry_id >= dtohs(header->entry_count)) {
+    // The entry is not present.
+    return false;
+  }
+
+  uint32_t result = dtohl(header->entries[input_entry_id]);
+  if (result == 0xffffffffu) {
+    return false;
+  }
+  *output_entry_id = static_cast<uint16_t>(result);
+  return true;
+}
+
+static bool is_word_aligned(const void* data) {
+  return (reinterpret_cast<uintptr_t>(data) & 0x03) == 0;
+}
+
+static bool IsValidIdmapHeader(const StringPiece& data) {
+  if (!is_word_aligned(data.data())) {
+    LOG(ERROR) << "Idmap header is not word aligned.";
+    return false;
+  }
+
+  if (data.size() < sizeof(Idmap_header)) {
+    LOG(ERROR) << "Idmap header is too small.";
+    return false;
+  }
+
+  const Idmap_header* header = reinterpret_cast<const Idmap_header*>(data.data());
+  if (dtohl(header->magic) != kIdmapMagic) {
+    LOG(ERROR) << StringPrintf("Invalid Idmap file: bad magic value (was 0x%08x, expected 0x%08x)",
+                               dtohl(header->magic), kIdmapMagic);
+    return false;
+  }
+
+  if (dtohl(header->version) != kIdmapCurrentVersion) {
+    // We are strict about versions because files with this format are auto-generated and don't need
+    // backwards compatibility.
+    LOG(ERROR) << StringPrintf("Version mismatch in Idmap (was 0x%08x, expected 0x%08x)",
+                               dtohl(header->version), kIdmapCurrentVersion);
+    return false;
+  }
+
+  if (!is_valid_package_id(dtohs(header->target_package_id))) {
+    LOG(ERROR) << StringPrintf("Target package ID in Idmap is invalid: 0x%02x",
+                               dtohs(header->target_package_id));
+    return false;
+  }
+
+  if (dtohs(header->type_count) > 255) {
+    LOG(ERROR) << StringPrintf("Idmap has too many type mappings (was %d, max 255)",
+                               (int)dtohs(header->type_count));
+    return false;
+  }
+  return true;
+}
+
+LoadedIdmap::LoadedIdmap(const Idmap_header* header) : header_(header) {
+  size_t length = strnlen(reinterpret_cast<const char*>(header_->overlay_path),
+                          arraysize(header_->overlay_path));
+  overlay_apk_path_.assign(reinterpret_cast<const char*>(header_->overlay_path), length);
+}
+
+std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_data) {
+  ATRACE_CALL();
+  if (!IsValidIdmapHeader(idmap_data)) {
+    return {};
+  }
+
+  const Idmap_header* header = reinterpret_cast<const Idmap_header*>(idmap_data.data());
+
+  // Can't use make_unique because LoadedImpl constructor is private.
+  std::unique_ptr<LoadedIdmap> loaded_idmap = std::unique_ptr<LoadedIdmap>(new LoadedIdmap(header));
+
+  const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(idmap_data.data()) + sizeof(*header);
+  size_t data_size = idmap_data.size() - sizeof(*header);
+
+  size_t type_maps_encountered = 0u;
+  while (data_size >= sizeof(IdmapEntry_header)) {
+    if (!is_word_aligned(data_ptr)) {
+      LOG(ERROR) << "Type mapping in Idmap is not word aligned";
+      return {};
+    }
+
+    // Validate the type IDs.
+    const IdmapEntry_header* entry_header = reinterpret_cast<const IdmapEntry_header*>(data_ptr);
+    if (!is_valid_type_id(dtohs(entry_header->target_type_id)) || !is_valid_type_id(dtohs(entry_header->overlay_type_id))) {
+      LOG(ERROR) << StringPrintf("Invalid type map (0x%02x -> 0x%02x)",
+                                 dtohs(entry_header->target_type_id),
+                                 dtohs(entry_header->overlay_type_id));
+      return {};
+    }
+
+    // Make sure there is enough space for the entries declared in the header.
+    if ((data_size - sizeof(*entry_header)) / sizeof(uint32_t) <
+        static_cast<size_t>(dtohs(entry_header->entry_count))) {
+      LOG(ERROR) << StringPrintf("Idmap too small for the number of entries (%d)",
+                                 (int)dtohs(entry_header->entry_count));
+      return {};
+    }
+
+    // Only add a non-empty overlay.
+    if (dtohs(entry_header->entry_count != 0)) {
+      loaded_idmap->type_map_[static_cast<uint8_t>(dtohs(entry_header->overlay_type_id))] =
+          entry_header;
+    }
+
+    const size_t entry_size_bytes =
+        sizeof(*entry_header) + (dtohs(entry_header->entry_count) * sizeof(uint32_t));
+    data_ptr += entry_size_bytes;
+    data_size -= entry_size_bytes;
+    type_maps_encountered++;
+  }
+
+  // Verify that we parsed all the type maps.
+  if (type_maps_encountered != static_cast<size_t>(dtohs(header->type_count))) {
+    LOG(ERROR) << "Parsed " << type_maps_encountered << " type maps but expected "
+               << (int)dtohs(header->type_count);
+    return {};
+  }
+  return std::move(loaded_idmap);
+}
+
+uint8_t LoadedIdmap::TargetPackageId() const {
+  return static_cast<uint8_t>(dtohs(header_->target_package_id));
+}
+
+const IdmapEntry_header* LoadedIdmap::GetEntryMapForType(uint8_t type_id) const {
+  auto iter = type_map_.find(type_id);
+  if (iter != type_map_.end()) {
+    return iter->second;
+  }
+  return nullptr;
+}
+
+}  // namespace android
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index bd7b804..b62fc81 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -37,7 +37,7 @@
 #include "androidfw/ResourceUtils.h"
 #include "androidfw/Util.h"
 
-using android::base::StringPrintf;
+using ::android::base::StringPrintf;
 
 namespace android {
 
@@ -61,6 +61,10 @@
   // and under which configurations it varies.
   const ResTable_typeSpec* type_spec;
 
+  // Pointer to the mmapped data where the IDMAP mappings for this type
+  // exist. May be nullptr if no IDMAP exists.
+  const IdmapEntry_header* idmap_entries;
+
   // The number of types that follow this struct.
   // There is a type for each configuration
   // that entries are defined for.
@@ -84,7 +88,10 @@
 // the Type structs.
 class TypeSpecPtrBuilder {
  public:
-  TypeSpecPtrBuilder(const ResTable_typeSpec* header) : header_(header) {}
+  explicit TypeSpecPtrBuilder(const ResTable_typeSpec* header,
+                              const IdmapEntry_header* idmap_header)
+      : header_(header), idmap_header_(idmap_header) {
+  }
 
   void AddType(const ResTable_type* type) {
     ResTable_config config;
@@ -99,6 +106,7 @@
     }
     TypeSpec* type_spec = (TypeSpec*)::malloc(sizeof(TypeSpec) + (types_.size() * sizeof(Type)));
     type_spec->type_spec = header_;
+    type_spec->idmap_entries = idmap_header_;
     type_spec->type_count = types_.size();
     memcpy(type_spec + 1, types_.data(), types_.size() * sizeof(Type));
     return TypeSpecPtr(type_spec);
@@ -108,6 +116,7 @@
   DISALLOW_COPY_AND_ASSIGN(TypeSpecPtrBuilder);
 
   const ResTable_typeSpec* header_;
+  const IdmapEntry_header* idmap_header_;
   std::vector<Type> types_;
 };
 
@@ -125,6 +134,14 @@
     return false;
   }
 
+  // If there is an IDMAP supplied with this package, translate the entry ID.
+  if (ptr->idmap_entries != nullptr) {
+    if (!LoadedIdmap::Lookup(ptr->idmap_entries, entry_idx, &entry_idx)) {
+      // There is no mapping, so the resource is not meant to be in this overlay package.
+      return false;
+    }
+  }
+
   // Don't bother checking if the entry ID is larger than
   // the number of entries.
   if (entry_idx >= dtohl(ptr->type_spec->entryCount)) {
@@ -225,7 +242,7 @@
   const size_t entries_offset = dtohl(header->entriesStart);
   const size_t offsets_length = sizeof(uint32_t) * entry_count;
 
-  if (offsets_offset + offsets_length > entries_offset) {
+  if (offsets_offset > entries_offset || entries_offset - offsets_offset < offsets_length) {
     LOG(ERROR) << "Entry offsets overlap actual entry data.";
     return false;
   }
@@ -269,13 +286,13 @@
           reinterpret_cast<const uint8_t*>(header) + offset);
       const size_t entry_size = dtohs(entry->size);
       if (entry_size < sizeof(*entry)) {
-        LOG(ERROR) << "ResTable_entry size " << entry_size << " is too small.";
+        LOG(ERROR) << "ResTable_entry size " << entry_size << " at index " << i << " is too small.";
         return false;
       }
 
       // Check the declared entrySize.
       if (entry_size > chunk.size() || offset > chunk.size() - entry_size) {
-        LOG(ERROR) << "ResTable_entry size " << entry_size << " is too large.";
+        LOG(ERROR) << "ResTable_entry size " << entry_size << " at index " << i << " is too large.";
         return false;
       }
 
@@ -286,13 +303,13 @@
 
         size_t map_entries_start = offset + entry_size;
         if (map_entries_start & 0x03) {
-          LOG(ERROR) << "Map entries start at unaligned offset.";
+          LOG(ERROR) << "Map entries at index " << i << " start at unaligned offset.";
           return false;
         }
 
         // Each entry is sizeof(ResTable_map) big.
         if (map_entry_count > ((chunk.size() - map_entries_start) / sizeof(ResTable_map))) {
-          LOG(ERROR) << "Too many map entries in ResTable_map_entry.";
+          LOG(ERROR) << "Too many map entries in ResTable_map_entry at index " << i << ".";
           return false;
         }
 
@@ -300,7 +317,9 @@
       } else {
         // There needs to be room for one Res_value struct.
         if (offset + entry_size > chunk.size() - sizeof(Res_value)) {
-          LOG(ERROR) << "No room for Res_value after ResTable_entry.";
+          LOG(ERROR) << "No room for Res_value after ResTable_entry at index " << i << " for type "
+                     << (int)header->id << " with config " << header->config.toString().string()
+                     << ".";
           return false;
         }
 
@@ -308,12 +327,12 @@
             reinterpret_cast<const uint8_t*>(entry) + entry_size);
         const size_t value_size = dtohs(value->size);
         if (value_size < sizeof(Res_value)) {
-          LOG(ERROR) << "Res_value is too small.";
+          LOG(ERROR) << "Res_value at index " << i << " is too small.";
           return false;
         }
 
         if (value_size > chunk.size() || offset + entry_size > chunk.size() - value_size) {
-          LOG(ERROR) << "Res_value size is too large.";
+          LOG(ERROR) << "Res_value size " << value_size << " at index " << i << " is too large.";
           return false;
         }
       }
@@ -412,10 +431,13 @@
   return 0u;
 }
 
-std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) {
+std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
+                                                   const LoadedIdmap* loaded_idmap) {
   ATRACE_CALL();
   std::unique_ptr<LoadedPackage> loaded_package{new LoadedPackage()};
 
+  // typeIdOffset was added at some point, but we still must recognize apps built before this
+  // was added.
   constexpr size_t kMinPackageSize =
       sizeof(ResTable_package) - sizeof(ResTable_package::typeIdOffset);
   const ResTable_package* header = chunk.header<ResTable_package, kMinPackageSize>();
@@ -430,6 +452,12 @@
     loaded_package->dynamic_ = true;
   }
 
+  if (loaded_idmap != nullptr) {
+    // This is an overlay and so it needs to pretend to be the target package.
+    loaded_package->package_id_ = loaded_idmap->TargetPackageId();
+    loaded_package->overlay_ = true;
+  }
+
   if (header->header.headerSize >= sizeof(ResTable_package)) {
     uint32_t type_id_offset = dtohl(header->typeIdOffset);
     if (type_id_offset > std::numeric_limits<uint8_t>::max()) {
@@ -490,7 +518,16 @@
             LOG(ERROR) << "Too many type configurations, overflow detected.";
             return {};
           }
-          loaded_package->type_specs_.editItemAt(last_type_idx) = std::move(type_spec_ptr);
+
+          // We only add the type to the package if there is no IDMAP, or if the type is
+          // overlaying something.
+          if (loaded_idmap == nullptr || type_spec_ptr->idmap_entries != nullptr) {
+            // If this is an overlay, insert it at the target type ID.
+            if (type_spec_ptr->idmap_entries != nullptr) {
+              last_type_idx = dtohs(type_spec_ptr->idmap_entries->target_type_id) - 1;
+            }
+            loaded_package->type_specs_.editItemAt(last_type_idx) = std::move(type_spec_ptr);
+          }
 
           types_builder = {};
           last_type_idx = 0;
@@ -531,7 +568,15 @@
         }
 
         last_type_idx = type_spec->id - 1;
-        types_builder = util::make_unique<TypeSpecPtrBuilder>(type_spec);
+
+        // If this is an overlay, associate the mapping of this type to the target type
+        // from the IDMAP.
+        const IdmapEntry_header* idmap_entry_header = nullptr;
+        if (loaded_idmap != nullptr) {
+          idmap_entry_header = loaded_idmap->GetEntryMapForType(type_spec->id);
+        }
+
+        types_builder = util::make_unique<TypeSpecPtrBuilder>(type_spec, idmap_entry_header);
       } break;
 
       case RES_TABLE_TYPE_TYPE: {
@@ -608,7 +653,16 @@
       LOG(ERROR) << "Too many type configurations, overflow detected.";
       return {};
     }
-    loaded_package->type_specs_.editItemAt(last_type_idx) = std::move(type_spec_ptr);
+
+    // We only add the type to the package if there is no IDMAP, or if the type is
+    // overlaying something.
+    if (loaded_idmap == nullptr || type_spec_ptr->idmap_entries != nullptr) {
+      // If this is an overlay, insert it at the target type ID.
+      if (type_spec_ptr->idmap_entries != nullptr) {
+        last_type_idx = dtohs(type_spec_ptr->idmap_entries->target_type_id) - 1;
+      }
+      loaded_package->type_specs_.editItemAt(last_type_idx) = std::move(type_spec_ptr);
+    }
   }
 
   if (iter.HadError()) {
@@ -618,7 +672,8 @@
   return loaded_package;
 }
 
-bool LoadedArsc::LoadTable(const Chunk& chunk, bool load_as_shared_library) {
+bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
+                           bool load_as_shared_library) {
   ATRACE_CALL();
   const ResTable_header* header = chunk.header<ResTable_header>();
   if (header == nullptr) {
@@ -652,13 +707,13 @@
       case RES_TABLE_PACKAGE_TYPE: {
         if (packages_seen + 1 > package_count) {
           LOG(ERROR) << "More package chunks were found than the " << package_count
-                     << " declared in the "
-                        "header.";
+                     << " declared in the header.";
           return false;
         }
         packages_seen++;
 
-        std::unique_ptr<LoadedPackage> loaded_package = LoadedPackage::Load(child_chunk);
+        std::unique_ptr<LoadedPackage> loaded_package =
+            LoadedPackage::Load(child_chunk, loaded_idmap);
         if (!loaded_package) {
           return false;
         }
@@ -684,7 +739,8 @@
   return true;
 }
 
-std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const void* data, size_t len, bool system,
+std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data,
+                                                   const LoadedIdmap* loaded_idmap, bool system,
                                                    bool load_as_shared_library) {
   ATRACE_CALL();
 
@@ -692,12 +748,12 @@
   std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc());
   loaded_arsc->system_ = system;
 
-  ChunkIterator iter(data, len);
+  ChunkIterator iter(data.data(), data.size());
   while (iter.HasNext()) {
     const Chunk chunk = iter.Next();
     switch (chunk.type()) {
       case RES_TABLE_TYPE:
-        if (!loaded_arsc->LoadTable(chunk, load_as_shared_library)) {
+        if (!loaded_arsc->LoadTable(chunk, loaded_idmap, load_as_shared_library)) {
           return {};
         }
         break;
@@ -717,4 +773,8 @@
   return std::move(loaded_arsc);
 }
 
+std::unique_ptr<const LoadedArsc> LoadedArsc::CreateEmpty() {
+  return std::unique_ptr<LoadedArsc>(new LoadedArsc());
+}
+
 }  // namespace android
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index 2e392d5..3a307fc 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -28,36 +28,63 @@
 
 namespace android {
 
+class LoadedIdmap;
+
 // Holds an APK.
 class ApkAssets {
  public:
+  // Creates an ApkAssets.
+  // If `system` is true, the package is marked as a system package, and allows some functions to
+  // filter out this package when computing what configurations/resources are available.
   static std::unique_ptr<const ApkAssets> Load(const std::string& path, bool system = false);
+
+  // Creates an ApkAssets, but forces any package with ID 0x7f to be loaded as a shared library.
+  // If `system` is true, the package is marked as a system package, and allows some functions to
+  // filter out this package when computing what configurations/resources are available.
   static std::unique_ptr<const ApkAssets> LoadAsSharedLibrary(const std::string& path,
                                                               bool system = false);
 
+  // Creates an ApkAssets from an IDMAP, which contains the original APK path, and the overlay
+  // data.
+  // If `system` is true, the package is marked as a system package, and allows some functions to
+  // filter out this package when computing what configurations/resources are available.
+  static std::unique_ptr<const ApkAssets> LoadOverlay(const std::string& idmap_path,
+                                                      bool system = false);
+
   std::unique_ptr<Asset> Open(const std::string& path,
                               Asset::AccessMode mode = Asset::AccessMode::ACCESS_RANDOM) const;
 
   bool ForEachFile(const std::string& path,
                    const std::function<void(const StringPiece&, FileType)>& f) const;
 
-  inline const std::string& GetPath() const { return path_; }
+  inline const std::string& GetPath() const {
+    return path_;
+  }
 
-  inline const LoadedArsc* GetLoadedArsc() const { return loaded_arsc_.get(); }
+  // This is never nullptr.
+  inline const LoadedArsc* GetLoadedArsc() const {
+    return loaded_arsc_.get();
+  }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ApkAssets);
 
-  static std::unique_ptr<const ApkAssets> LoadImpl(const std::string& path, bool system,
-                                                   bool load_as_shared_library);
+  static std::unique_ptr<const ApkAssets> LoadImpl(const std::string& path,
+                                                   std::unique_ptr<Asset> idmap_asset,
+                                                   std::unique_ptr<const LoadedIdmap> loaded_idmap,
+                                                   bool system, bool load_as_shared_library);
 
-  ApkAssets();
+  // Creates an Asset from any file on the file system.
+  static std::unique_ptr<Asset> CreateAssetFromFile(const std::string& path);
+
+  ApkAssets(void* unmanaged_handle, const std::string& path);
 
   using ZipArchivePtr = std::unique_ptr<void, void(*)(void*)>;
 
   ZipArchivePtr zip_handle_;
-  std::string path_;
+  const std::string path_;
   std::unique_ptr<Asset> resources_asset_;
+  std::unique_ptr<Asset> idmap_asset_;
   std::unique_ptr<const LoadedArsc> loaded_arsc_;
 };
 
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index fd94144..b29bc3a 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -96,24 +96,29 @@
   // new resource IDs.
   bool SetApkAssets(const std::vector<const ApkAssets*>& apk_assets, bool invalidate_caches = true);
 
-  inline const std::vector<const ApkAssets*> GetApkAssets() const { return apk_assets_; }
+  inline const std::vector<const ApkAssets*> GetApkAssets() const {
+    return apk_assets_;
+  }
 
   // Returns the string pool for the given asset cookie.
-  // Use the string pool returned here with a valid Res_value object of
-  // type Res_value::TYPE_STRING.
+  // Use the string pool returned here with a valid Res_value object of type Res_value::TYPE_STRING.
   const ResStringPool* GetStringPoolForCookie(ApkAssetsCookie cookie) const;
 
   // Returns the DynamicRefTable for the given package ID.
+  // This may be nullptr if the APK represented by `cookie` has no resource table.
   const DynamicRefTable* GetDynamicRefTableForPackage(uint32_t package_id) const;
 
   // Returns the DynamicRefTable for the ApkAssets represented by the cookie.
+  // This may be nullptr if the APK represented by `cookie` has no resource table.
   const DynamicRefTable* GetDynamicRefTableForCookie(ApkAssetsCookie cookie) const;
 
   // Sets/resets the configuration for this AssetManager. This will cause all
   // caches that are related to the configuration change to be invalidated.
   void SetConfiguration(const ResTable_config& configuration);
 
-  inline const ResTable_config& GetConfiguration() const { return configuration_; }
+  inline const ResTable_config& GetConfiguration() const {
+    return configuration_;
+  }
 
   // Returns all configurations for which there are resources defined. This includes resource
   // configurations in all the ApkAssets set for this AssetManager.
@@ -227,6 +232,14 @@
   // Creates a new Theme from this AssetManager.
   std::unique_ptr<Theme> NewTheme();
 
+  template <typename Func>
+  void ForEachPackage(Func func) {
+    for (const PackageGroup& package_group : package_groups_) {
+      func(package_group.packages_.front()->GetPackageName(),
+           package_group.dynamic_ref_table.mAssignedPackageId);
+    }
+  }
+
   void DumpToLog() const;
 
  private:
diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h
new file mode 100644
index 0000000..fd02e6f
--- /dev/null
+++ b/libs/androidfw/include/androidfw/Idmap.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef IDMAP_H_
+#define IDMAP_H_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "android-base/macros.h"
+
+#include "androidfw/StringPiece.h"
+
+namespace android {
+
+struct Idmap_header;
+struct IdmapEntry_header;
+
+// Represents a loaded/parsed IDMAP for a Runtime Resource Overlay (RRO).
+// An RRO and its target APK have different resource IDs assigned to their resources. Overlaying
+// a resource is done by resource name. An IDMAP is a generated mapping between the resource IDs
+// of the RRO and the target APK for each resource with the same name.
+// A LoadedIdmap can be set alongside the overlay's LoadedArsc to allow the overlay ApkAssets to
+// masquerade as the target ApkAssets resources.
+class LoadedIdmap {
+ public:
+  // Loads an IDMAP from a chunk of memory. Returns nullptr if the IDMAP data was malformed.
+  static std::unique_ptr<const LoadedIdmap> Load(const StringPiece& idmap_data);
+
+  // Performs a lookup of the expected entry ID for the given IDMAP entry header.
+  // Returns true if the mapping exists and fills `output_entry_id` with the result.
+  static bool Lookup(const IdmapEntry_header* header, uint16_t input_entry_id,
+                     uint16_t* output_entry_id);
+
+  // Returns the package ID for which this overlay should apply.
+  uint8_t TargetPackageId() const;
+
+  // Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated.
+  inline const std::string& OverlayApkPath() const {
+    return overlay_apk_path_;
+  }
+
+  // Returns the mapping of target entry ID to overlay entry ID for the given target type.
+  const IdmapEntry_header* GetEntryMapForType(uint8_t type_id) const;
+
+ protected:
+  // Exposed as protected so that tests can subclass and mock this class out.
+  LoadedIdmap() = default;
+
+  const Idmap_header* header_ = nullptr;
+  std::string overlay_apk_path_;
+  std::unordered_map<uint8_t, const IdmapEntry_header*> type_map_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(LoadedIdmap);
+
+  explicit LoadedIdmap(const Idmap_header* header);
+};
+
+}  // namespace android
+
+#endif  // IDMAP_H_
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index f30b158..1f272e8 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -25,6 +25,7 @@
 
 #include "androidfw/ByteBucketArray.h"
 #include "androidfw/Chunk.h"
+#include "androidfw/Idmap.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/Util.h"
 
@@ -70,20 +71,36 @@
                  uint32_t* out_flags) const;
 
   // Returns the string pool where type names are stored.
-  inline const ResStringPool* GetTypeStringPool() const { return &type_string_pool_; }
+  inline const ResStringPool* GetTypeStringPool() const {
+    return &type_string_pool_;
+  }
 
   // Returns the string pool where the names of resource entries are stored.
-  inline const ResStringPool* GetKeyStringPool() const { return &key_string_pool_; }
+  inline const ResStringPool* GetKeyStringPool() const {
+    return &key_string_pool_;
+  }
 
-  inline const std::string& GetPackageName() const { return package_name_; }
+  inline const std::string& GetPackageName() const {
+    return package_name_;
+  }
 
-  inline int GetPackageId() const { return package_id_; }
+  inline int GetPackageId() const {
+    return package_id_;
+  }
 
   // Returns true if this package is dynamic (shared library) and needs to have an ID assigned.
-  inline bool IsDynamic() const { return dynamic_; }
+  inline bool IsDynamic() const {
+    return dynamic_;
+  }
 
   // Returns true if this package originates from a system provided resource.
-  inline bool IsSystem() const { return system_; }
+  inline bool IsSystem() const {
+    return system_;
+  }
+
+  inline bool IsOverlay() const {
+    return overlay_;
+  }
 
   // Returns the map of package name to package ID used in this LoadedPackage. At runtime, a
   // package could have been assigned a different package ID than what this LoadedPackage was
@@ -111,7 +128,7 @@
  private:
   DISALLOW_COPY_AND_ASSIGN(LoadedPackage);
 
-  static std::unique_ptr<LoadedPackage> Load(const Chunk& chunk);
+  static std::unique_ptr<LoadedPackage> Load(const Chunk& chunk, const LoadedIdmap* loaded_idmap);
 
   LoadedPackage() = default;
 
@@ -122,6 +139,7 @@
   int type_id_offset_ = 0;
   bool dynamic_ = false;
   bool system_ = false;
+  bool overlay_ = false;
 
   ByteBucketArray<util::unique_cptr<TypeSpec>> type_specs_;
   std::vector<DynamicPackageEntry> dynamic_package_map_;
@@ -137,14 +155,21 @@
   // If `load_as_shared_library` is set to true, the application package (0x7f) is treated
   // as a shared library (0x00). When loaded into an AssetManager, the package will be assigned an
   // ID.
-  static std::unique_ptr<const LoadedArsc> Load(const void* data, size_t len, bool system = false,
+  static std::unique_ptr<const LoadedArsc> Load(const StringPiece& data,
+                                                const LoadedIdmap* loaded_idmap = nullptr,
+                                                bool system = false,
                                                 bool load_as_shared_library = false);
 
+  // Create an empty LoadedArsc. This is used when an APK has no resources.arsc.
+  static std::unique_ptr<const LoadedArsc> CreateEmpty();
+
   ~LoadedArsc();
 
   // Returns the string pool where all string resource values
   // (Res_value::dataType == Res_value::TYPE_STRING) are indexed.
-  inline const ResStringPool* GetStringPool() const { return &global_string_pool_; }
+  inline const ResStringPool* GetStringPool() const {
+    return &global_string_pool_;
+  }
 
   // Finds the resource with ID `resid` with the best value for configuration `config`.
   // The parameter `out_entry` will be filled with the resulting resource entry.
@@ -157,7 +182,9 @@
   const LoadedPackage* GetPackageForId(uint32_t resid) const;
 
   // Returns true if this is a system provided resource.
-  inline bool IsSystem() const { return system_; }
+  inline bool IsSystem() const {
+    return system_;
+  }
 
   // Returns a vector of LoadedPackage pointers, representing the packages in this LoadedArsc.
   inline const std::vector<std::unique_ptr<const LoadedPackage>>& GetPackages() const {
@@ -168,7 +195,7 @@
   DISALLOW_COPY_AND_ASSIGN(LoadedArsc);
 
   LoadedArsc() = default;
-  bool LoadTable(const Chunk& chunk, bool load_as_shared_library);
+  bool LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, bool load_as_shared_library);
 
   ResStringPool global_string_pool_;
   std::vector<std::unique_ptr<const LoadedPackage>> packages_;
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 66c66c2..8f858b6 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -38,6 +38,9 @@
 
 namespace android {
 
+constexpr const static uint32_t kIdmapMagic = 0x504D4449u;
+constexpr const static uint32_t kIdmapCurrentVersion = 0x00000001u;
+
 /**
  * In C++11, char16_t is defined as *at least* 16 bits. We do a lot of
  * casting on raw data and expect char16_t to be exactly 16 bits.
@@ -1583,6 +1586,30 @@
     uint16_t packageName[128];
 };
 
+struct alignas(uint32_t) Idmap_header {
+  // Always 0x504D4449 ('IDMP')
+  uint32_t magic;
+
+  uint32_t version;
+
+  uint32_t target_crc32;
+  uint32_t overlay_crc32;
+
+  uint8_t target_path[256];
+  uint8_t overlay_path[256];
+
+  uint16_t target_package_id;
+  uint16_t type_count;
+} __attribute__((packed));
+
+struct alignas(uint32_t) IdmapEntry_header {
+  uint16_t target_type_id;
+  uint16_t overlay_type_id;
+  uint16_t entry_count;
+  uint16_t entry_id_offset;
+  uint32_t entries[0];
+} __attribute__((packed));
+
 class AssetManager2;
 
 /**
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
deleted file mode 100644
index 921fd14..0000000
--- a/libs/androidfw/tests/Android.mk
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# Copyright (C) 2014 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.
-#
-
-# ==========================================================
-# Setup some common variables for the different build
-# targets here.
-# ==========================================================
-LOCAL_PATH:= $(call my-dir)
-
-testFiles := \
-    ApkAssets_test.cpp \
-    AppAsLib_test.cpp \
-    Asset_test.cpp \
-    AssetManager2_test.cpp \
-    AttributeFinder_test.cpp \
-    AttributeResolution_test.cpp \
-    ByteBucketArray_test.cpp \
-    Config_test.cpp \
-    ConfigLocale_test.cpp \
-    Idmap_test.cpp \
-    LoadedArsc_test.cpp \
-    ResourceUtils_test.cpp \
-    ResTable_test.cpp \
-    Split_test.cpp \
-    StringPiece_test.cpp \
-    TestHelpers.cpp \
-    TestMain.cpp \
-    Theme_test.cpp \
-    TypeWrappers_test.cpp \
-    ZipUtils_test.cpp
-
-benchmarkFiles := \
-    AssetManager2_bench.cpp \
-    BenchMain.cpp \
-    BenchmarkHelpers.cpp \
-    SparseEntry_bench.cpp \
-    TestHelpers.cpp \
-    Theme_bench.cpp
-
-androidfw_test_cflags := \
-    -Wall \
-    -Werror \
-    -Wunused \
-    -Wunreachable-code \
-    -Wno-missing-field-initializers
-
-# gtest is broken.
-androidfw_test_cflags += -Wno-unnamed-type-template-args
-
-# ==========================================================
-# Build the host tests: libandroidfw_tests
-# ==========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libandroidfw_tests
-LOCAL_CFLAGS := $(androidfw_test_cflags)
-LOCAL_SRC_FILES := $(testFiles)
-LOCAL_STATIC_LIBRARIES := \
-    libandroidfw \
-    libbase \
-    libutils \
-    libcutils \
-    liblog \
-    libz \
-    libziparchive
-LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data
-
-include $(BUILD_HOST_NATIVE_TEST)
-
-# ==========================================================
-# Build the device tests: libandroidfw_tests
-# ==========================================================
-ifneq ($(SDK_ONLY),true)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libandroidfw_tests
-LOCAL_CFLAGS := $(androidfw_test_cflags)
-LOCAL_SRC_FILES := $(testFiles) \
-    BackupData_test.cpp \
-    ObbFile_test.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-    libandroidfw \
-    libbase \
-    libcutils \
-    libutils \
-    libui \
-    libziparchive 
-LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data
-
-include $(BUILD_NATIVE_TEST)
-
-# ==========================================================
-# Build the device benchmarks: libandroidfw_benchmarks
-# ==========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libandroidfw_benchmarks
-LOCAL_CFLAGS := $(androidfw_test_cflags)
-LOCAL_SRC_FILES := $(benchmarkFiles)
-LOCAL_STATIC_LIBRARIES := \
-    libgoogle-benchmark
-LOCAL_SHARED_LIBRARIES := \
-    libandroidfw \
-    libbase \
-    libcutils \
-    libutils \
-    libziparchive
-LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data
-
-include $(BUILD_NATIVE_TEST)
-endif # Not SDK_ONLY
-
diff --git a/libs/androidfw/tests/ApkAssets_test.cpp b/libs/androidfw/tests/ApkAssets_test.cpp
index c85b0b9..2766ce1 100644
--- a/libs/androidfw/tests/ApkAssets_test.cpp
+++ b/libs/androidfw/tests/ApkAssets_test.cpp
@@ -17,12 +17,14 @@
 #include "androidfw/ApkAssets.h"
 
 #include "android-base/file.h"
+#include "android-base/test_utils.h"
 #include "android-base/unique_fd.h"
+#include "androidfw/Util.h"
 
 #include "TestHelpers.h"
 #include "data/basic/R.h"
 
-using com::android::basic::R;
+using ::com::android::basic::R;
 
 namespace android {
 
@@ -54,6 +56,37 @@
   EXPECT_TRUE(loaded_arsc->GetPackages()[0]->IsDynamic());
 }
 
+TEST(ApkAssetsTest, LoadApkWithIdmap) {
+  std::string contents;
+  ResTable target_table;
+  const std::string target_path = GetTestDataPath() + "/basic/basic.apk";
+  ASSERT_TRUE(ReadFileFromZipToString(target_path, "resources.arsc", &contents));
+  ASSERT_EQ(NO_ERROR, target_table.add(contents.data(), contents.size(), 0, true /*copyData*/));
+
+  ResTable overlay_table;
+  const std::string overlay_path = GetTestDataPath() + "/overlay/overlay.apk";
+  ASSERT_TRUE(ReadFileFromZipToString(overlay_path, "resources.arsc", &contents));
+  ASSERT_EQ(NO_ERROR, overlay_table.add(contents.data(), contents.size(), 0, true /*copyData*/));
+
+  util::unique_cptr<void> idmap_data;
+  void* temp_data;
+  size_t idmap_len;
+
+  ASSERT_EQ(NO_ERROR, target_table.createIdmap(overlay_table, 0u, 0u, target_path.c_str(),
+                                               overlay_path.c_str(), &temp_data, &idmap_len));
+  idmap_data.reset(temp_data);
+
+  TemporaryFile tf;
+  ASSERT_TRUE(base::WriteFully(tf.fd, idmap_data.get(), idmap_len));
+  close(tf.fd);
+
+  // Open something so that the destructor of TemporaryFile closes a valid fd.
+  tf.fd = open("/dev/null", O_WRONLY);
+
+  std::unique_ptr<const ApkAssets> loaded_overlay_apk = ApkAssets::LoadOverlay(tf.path);
+  ASSERT_NE(nullptr, loaded_overlay_apk);
+}
+
 TEST(ApkAssetsTest, CreateAndDestroyAssetKeepsApkAssetsOpen) {
   std::unique_ptr<const ApkAssets> loaded_apk =
       ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
diff --git a/libs/androidfw/tests/AssetManager2_bench.cpp b/libs/androidfw/tests/AssetManager2_bench.cpp
index 67de741..99a07a5 100644
--- a/libs/androidfw/tests/AssetManager2_bench.cpp
+++ b/libs/androidfw/tests/AssetManager2_bench.cpp
@@ -23,7 +23,6 @@
 #include "androidfw/ResourceTypes.h"
 
 #include "BenchmarkHelpers.h"
-#include "TestHelpers.h"
 #include "data/basic/R.h"
 #include "data/libclient/R.h"
 #include "data/styles/R.h"
diff --git a/libs/androidfw/tests/BenchMain.cpp b/libs/androidfw/tests/BenchMain.cpp
index 105c5f9..58fc54a 100644
--- a/libs/androidfw/tests/BenchMain.cpp
+++ b/libs/androidfw/tests/BenchMain.cpp
@@ -18,7 +18,7 @@
 
 #include "benchmark/benchmark.h"
 
-#include "TestHelpers.h"
+#include "BenchmarkHelpers.h"
 
 int main(int argc, char** argv) {
   ::benchmark::Initialize(&argc, argv);
diff --git a/libs/androidfw/tests/BenchmarkHelpers.h b/libs/androidfw/tests/BenchmarkHelpers.h
index fc36664..0bb96b5 100644
--- a/libs/androidfw/tests/BenchmarkHelpers.h
+++ b/libs/androidfw/tests/BenchmarkHelpers.h
@@ -14,21 +14,22 @@
  * limitations under the License.
  */
 
-#ifndef TESTS_BENCHMARKHELPERS_H_
-#define TESTS_BENCHMARKHELPERS_H_
+#ifndef ANDROIDFW_TESTS_BENCHMARKHELPERS_H
+#define ANDROIDFW_TESTS_BENCHMARKHELPERS_H
 
 #include <string>
 #include <vector>
 
+#include "androidfw/ResourceTypes.h"
 #include "benchmark/benchmark.h"
 
-#include "androidfw/ResourceTypes.h"
+#include "CommonHelpers.h"
 
 namespace android {
 
 void GetResourceBenchmarkOld(const std::vector<std::string>& paths, const ResTable_config* config,
-                             uint32_t resid, benchmark::State& state);
+                             uint32_t resid, ::benchmark::State& state);
 
 }  // namespace android
 
-#endif /* TESTS_BENCHMARKHELPERS_H_ */
+#endif  // ANDROIDFW_TESTS_BENCHMARKHELPERS_H
diff --git a/libs/androidfw/tests/CommonHelpers.cpp b/libs/androidfw/tests/CommonHelpers.cpp
new file mode 100644
index 0000000..faa5350
--- /dev/null
+++ b/libs/androidfw/tests/CommonHelpers.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "CommonHelpers.h"
+
+#include <iostream>
+
+#include "android-base/file.h"
+#include "android-base/logging.h"
+#include "android-base/strings.h"
+
+namespace android {
+
+static std::string sTestDataPath;
+
+void InitializeTest(int* argc, char** argv) {
+  // Set the default test data path to be the executable path directory + data.
+  SetTestDataPath(base::GetExecutableDirectory() + "/tests/data");
+
+  for (int i = 1; i < *argc; i++) {
+    const std::string arg = argv[i];
+    if (base::StartsWith(arg, "--testdata=")) {
+      SetTestDataPath(arg.substr(strlen("--testdata=")));
+      for (int j = i; j != *argc; j++) {
+        argv[j] = argv[j + 1];
+      }
+      --(*argc);
+      --i;
+    } else if (arg == "-h" || arg == "--help") {
+      std::cerr << "\nAdditional options specific to this test:\n"
+                   "  --testdata=[PATH]\n"
+                   "      Specify the location of test data used within the tests.\n";
+      exit(1);
+    }
+  }
+}
+
+void SetTestDataPath(const std::string& path) {
+  sTestDataPath = path;
+}
+
+const std::string& GetTestDataPath() {
+  CHECK(!sTestDataPath.empty()) << "no test data path set.";
+  return sTestDataPath;
+}
+
+std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx) {
+  String8 str = pool->string8ObjectAt(idx);
+  return std::string(str.string(), str.length());
+}
+
+}  // namespace android
diff --git a/libs/androidfw/tests/CommonHelpers.h b/libs/androidfw/tests/CommonHelpers.h
new file mode 100644
index 0000000..c160fbb
--- /dev/null
+++ b/libs/androidfw/tests/CommonHelpers.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROIDFW_TEST_COMMON_HELPERS_H
+#define ANDROIDFW_TEST_COMMON_HELPERS_H
+
+#include <ostream>
+#include <string>
+
+#include "androidfw/ResourceTypes.h"
+#include "utils/String16.h"
+#include "utils/String8.h"
+
+namespace android {
+
+void InitializeTest(int* argc, char** argv);
+
+enum { MAY_NOT_BE_BAG = false };
+
+void SetTestDataPath(const std::string& path);
+
+const std::string& GetTestDataPath();
+
+std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx);
+
+static inline bool operator==(const ResTable_config& a, const ResTable_config& b) {
+  return a.compare(b) == 0;
+}
+
+static inline ::std::ostream& operator<<(::std::ostream& out, const String8& str) {
+  return out << str.string();
+}
+
+static inline ::std::ostream& operator<<(::std::ostream& out, const String16& str) {
+  return out << String8(str).string();
+}
+
+static inline ::std::ostream& operator<<(::std::ostream& out, const ResTable_config& c) {
+  return out << c.toString();
+}
+
+}  // namespace android
+
+#endif  // ANDROIDFW_TEST_COMMON_HELPERS_H
diff --git a/libs/androidfw/tests/Idmap_test.cpp b/libs/androidfw/tests/Idmap_test.cpp
index d12be18..9eb4a13 100644
--- a/libs/androidfw/tests/Idmap_test.cpp
+++ b/libs/androidfw/tests/Idmap_test.cpp
@@ -22,7 +22,7 @@
 #include "TestHelpers.h"
 #include "data/basic/R.h"
 
-using com::android::basic::R;
+using ::com::android::basic::R;
 
 namespace android {
 
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index 756869f..2b72d14 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -32,8 +32,7 @@
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/styles/styles.apk", "resources.arsc",
                                       &contents));
 
-  std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
   ASSERT_NE(nullptr, loaded_arsc);
 
   const std::vector<std::unique_ptr<const LoadedPackage>>& packages = loaded_arsc->GetPackages();
@@ -59,8 +58,7 @@
   ASSERT_TRUE(
       ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc", &contents));
 
-  std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
   ASSERT_NE(nullptr, loaded_arsc);
 
   ResTable_config desired_config;
@@ -82,8 +80,7 @@
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib_one/lib_one.apk", "resources.arsc",
                                       &contents));
 
-  std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
   ASSERT_NE(nullptr, loaded_arsc);
 
   const auto& packages = loaded_arsc->GetPackages();
@@ -104,8 +101,7 @@
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/libclient/libclient.apk",
                                       "resources.arsc", &contents));
 
-  std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
   ASSERT_NE(nullptr, loaded_arsc);
 
   const auto& packages = loaded_arsc->GetPackages();
@@ -132,8 +128,9 @@
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/appaslib/appaslib.apk",
                                       "resources.arsc", &contents));
 
-  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(
-      contents.data(), contents.size(), false /*system*/, true /*load_as_shared_library*/);
+  std::unique_ptr<const LoadedArsc> loaded_arsc =
+      LoadedArsc::Load(StringPiece(contents), nullptr /*loaded_idmap*/, false /*system*/,
+                       true /*load_as_shared_library*/);
   ASSERT_NE(nullptr, loaded_arsc);
 
   const auto& packages = loaded_arsc->GetPackages();
@@ -147,8 +144,7 @@
   std::string contents;
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/feature/feature.apk", "resources.arsc",
                                       &contents));
-  std::unique_ptr<const LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
   ASSERT_NE(nullptr, loaded_arsc);
 
   ResTable_config desired_config;
@@ -174,6 +170,54 @@
   EXPECT_EQ(std::string("string"), type_name);
 }
 
+class MockLoadedIdmap : public LoadedIdmap {
+ public:
+  MockLoadedIdmap() : LoadedIdmap() {
+    local_header_.magic = kIdmapMagic;
+    local_header_.version = kIdmapCurrentVersion;
+    local_header_.target_package_id = 0x08;
+    local_header_.type_count = 1;
+    header_ = &local_header_;
+
+    entry_header = util::unique_cptr<IdmapEntry_header>(
+        (IdmapEntry_header*)::malloc(sizeof(IdmapEntry_header) + sizeof(uint32_t)));
+    entry_header->target_type_id = 0x03;
+    entry_header->overlay_type_id = 0x02;
+    entry_header->entry_id_offset = 1;
+    entry_header->entry_count = 1;
+    entry_header->entries[0] = 0x00000000u;
+    type_map_[entry_header->overlay_type_id] = entry_header.get();
+  }
+
+ private:
+  Idmap_header local_header_;
+  util::unique_cptr<IdmapEntry_header> entry_header;
+};
+
+TEST(LoadedArscTest, LoadOverlay) {
+  std::string contents, overlay_contents;
+  ASSERT_TRUE(
+      ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc", &contents));
+  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlay/overlay.apk", "resources.arsc",
+                                      &overlay_contents));
+
+  MockLoadedIdmap loaded_idmap;
+
+  std::unique_ptr<const LoadedArsc> loaded_arsc =
+      LoadedArsc::Load(StringPiece(overlay_contents), &loaded_idmap);
+  ASSERT_NE(nullptr, loaded_arsc);
+
+  ResTable_config desired_config;
+  memset(&desired_config, 0, sizeof(desired_config));
+
+  LoadedArscEntry entry;
+  ResTable_config selected_config;
+  uint32_t flags;
+
+  ASSERT_TRUE(
+      loaded_arsc->FindEntry(0x08030001u, desired_config, &entry, &selected_config, &flags));
+}
+
 // structs with size fields (like Res_value, ResTable_entry) should be
 // backwards and forwards compatible (aka checking the size field against
 // sizeof(Res_value) might not be backwards compatible.
diff --git a/libs/androidfw/tests/SparseEntry_bench.cpp b/libs/androidfw/tests/SparseEntry_bench.cpp
index 1ebf7ce..d6dc07d 100644
--- a/libs/androidfw/tests/SparseEntry_bench.cpp
+++ b/libs/androidfw/tests/SparseEntry_bench.cpp
@@ -18,7 +18,6 @@
 #include "androidfw/ResourceTypes.h"
 
 #include "BenchmarkHelpers.h"
-#include "TestHelpers.h"
 #include "data/sparse/R.h"
 
 namespace sparse = com::android::sparse;
diff --git a/libs/androidfw/tests/TestHelpers.cpp b/libs/androidfw/tests/TestHelpers.cpp
index 1e763a5..9e320a2 100644
--- a/libs/androidfw/tests/TestHelpers.cpp
+++ b/libs/androidfw/tests/TestHelpers.cpp
@@ -16,67 +16,22 @@
 
 #include "TestHelpers.h"
 
-#include <libgen.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-
-#include "android-base/file.h"
-#include "android-base/logging.h"
-#include "android-base/strings.h"
 #include "ziparchive/zip_archive.h"
 
+using ::testing::AssertionFailure;
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+
 namespace android {
 
-static std::string sTestDataPath;
-
-// Extract the directory of the current executable path.
-static std::string GetExecutableDir() {
-  const std::string path = base::GetExecutablePath();
-  std::unique_ptr<char, decltype(&std::free)> mutable_path = {strdup(path.c_str()), std::free};
-  std::string executable_dir = dirname(mutable_path.get());
-  return executable_dir;
-}
-
-void InitializeTest(int* argc, char** argv) {
-  // Set the default test data path to be the executable path directory.
-  SetTestDataPath(GetExecutableDir());
-
-  for (int i = 1; i < *argc; i++) {
-    const std::string arg = argv[i];
-    if (base::StartsWith(arg, "--testdata=")) {
-      SetTestDataPath(arg.substr(strlen("--testdata=")));
-      for (int j = i; j != *argc; j++) {
-        argv[j] = argv[j + 1];
-      }
-      --(*argc);
-      --i;
-    } else if (arg == "-h" || arg == "--help") {
-      std::cerr << "\nAdditional options specific to this test:\n"
-                   "  --testdata=[PATH]\n"
-                   "      Specify the location of test data used within the tests.\n";
-      exit(1);
-    }
-  }
-}
-
-void SetTestDataPath(const std::string& path) { sTestDataPath = path; }
-
-const std::string& GetTestDataPath() {
-  CHECK(!sTestDataPath.empty()) << "no test data path set.";
-  return sTestDataPath;
-}
-
-::testing::AssertionResult ReadFileFromZipToString(const std::string& zip_path,
-                                                   const std::string& file,
-                                                   std::string* out_contents) {
+AssertionResult ReadFileFromZipToString(const std::string& zip_path, const std::string& file,
+                                        std::string* out_contents) {
   out_contents->clear();
   ::ZipArchiveHandle handle;
   int32_t result = OpenArchive(zip_path.c_str(), &handle);
   if (result != 0) {
-    return ::testing::AssertionFailure() << "Failed to open zip '" << zip_path
-                                         << "': " << ::ErrorCodeString(result);
+    return AssertionFailure() << "Failed to open zip '" << zip_path
+                              << "': " << ::ErrorCodeString(result);
   }
 
   ::ZipString name(file.c_str());
@@ -84,8 +39,8 @@
   result = ::FindEntry(handle, name, &entry);
   if (result != 0) {
     ::CloseArchive(handle);
-    return ::testing::AssertionFailure() << "Could not find file '" << file << "' in zip '"
-                                         << zip_path << "' : " << ::ErrorCodeString(result);
+    return AssertionFailure() << "Could not find file '" << file << "' in zip '" << zip_path
+                              << "' : " << ::ErrorCodeString(result);
   }
 
   out_contents->resize(entry.uncompressed_length);
@@ -94,41 +49,36 @@
       out_contents->size());
   if (result != 0) {
     ::CloseArchive(handle);
-    return ::testing::AssertionFailure() << "Failed to extract file '" << file << "' from zip '"
-                                         << zip_path << "': " << ::ErrorCodeString(result);
+    return AssertionFailure() << "Failed to extract file '" << file << "' from zip '" << zip_path
+                              << "': " << ::ErrorCodeString(result);
   }
 
   ::CloseArchive(handle);
-  return ::testing::AssertionSuccess();
+  return AssertionSuccess();
 }
 
-::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
-                                         const char* expected_str) {
+AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
+                              const char* expected_str) {
   Res_value val;
   ssize_t block = table.getResource(resource_id, &val, MAY_NOT_BE_BAG);
   if (block < 0) {
-    return ::testing::AssertionFailure() << "could not find resource";
+    return AssertionFailure() << "could not find resource";
   }
 
   if (val.dataType != Res_value::TYPE_STRING) {
-    return ::testing::AssertionFailure() << "resource is not a string";
+    return AssertionFailure() << "resource is not a string";
   }
 
   const ResStringPool* pool = table.getTableStringBlock(block);
   if (pool == NULL) {
-    return ::testing::AssertionFailure() << "table has no string pool for block " << block;
+    return AssertionFailure() << "table has no string pool for block " << block;
   }
 
   const String8 actual_str = pool->string8ObjectAt(val.data);
   if (String8(expected_str) != actual_str) {
-    return ::testing::AssertionFailure() << actual_str.string();
+    return AssertionFailure() << actual_str.string();
   }
-  return ::testing::AssertionSuccess() << actual_str.string();
-}
-
-std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx) {
-  String8 str = pool->string8ObjectAt(idx);
-  return std::string(str.string(), str.length());
+  return AssertionSuccess() << actual_str.string();
 }
 
 }  // namespace android
diff --git a/libs/androidfw/tests/TestHelpers.h b/libs/androidfw/tests/TestHelpers.h
index ec78b2a..43a9955 100644
--- a/libs/androidfw/tests/TestHelpers.h
+++ b/libs/androidfw/tests/TestHelpers.h
@@ -14,53 +14,25 @@
  * limitations under the License.
  */
 
-#ifndef TEST_HELPERS_H_
-#define TEST_HELPERS_H_
+#ifndef ANDROIDFW_TEST_TESTHELPERS_H
+#define ANDROIDFW_TEST_TESTHELPERS_H
 
-#include <ostream>
 #include <string>
-#include <vector>
 
 #include "androidfw/ResourceTypes.h"
 #include "gtest/gtest.h"
-#include "utils/String16.h"
-#include "utils/String8.h"
 
-static inline ::std::ostream& operator<<(::std::ostream& out, const android::String8& str) {
-  return out << str.string();
-}
-
-static inline ::std::ostream& operator<<(::std::ostream& out, const android::String16& str) {
-  return out << android::String8(str).string();
-}
+#include "CommonHelpers.h"
 
 namespace android {
 
-void InitializeTest(int* argc, char** argv);
-
-enum { MAY_NOT_BE_BAG = false };
-
-void SetTestDataPath(const std::string& path);
-
-const std::string& GetTestDataPath();
-
 ::testing::AssertionResult ReadFileFromZipToString(const std::string& zip_path,
                                                    const std::string& file,
                                                    std::string* out_contents);
 
-static inline bool operator==(const ResTable_config& a, const ResTable_config& b) {
-  return a.compare(b) == 0;
-}
-
-static inline ::std::ostream& operator<<(::std::ostream& out, const ResTable_config& c) {
-  return out << c.toString().string();
-}
-
 ::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
                                          const char* expected_str);
 
-std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx);
-
 }  // namespace android
 
-#endif  // TEST_HELPERS_H_
+#endif  // ANDROIDFW_TEST_TESTHELPERS_H
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 124182f..ad6ce2c4 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -250,7 +250,17 @@
         // If enabled, every GLES call is wrapped & error checked
         // Has moderate overhead
         "hwui_enable_opengl_validation",
-],
+    ],
+
+    // Build libhwui with PGO by default.
+    // Location of PGO profile data is defined in build/soong/cc/pgo.go
+    // and is separate from hwui.
+    // To turn it off, set ANDROID_PGO_NO_PROFILE_USE environment variable.
+    pgo: {
+        instrumentation: true,
+        profile_file: "hwui/hwui.profdata",
+        benchmarks: ["hwui"],
+    },
 }
 
 // ------------------------
diff --git a/libs/hwui/ProfileDataContainer.cpp b/libs/hwui/ProfileDataContainer.cpp
index cbf3eb3..70a77ed 100644
--- a/libs/hwui/ProfileDataContainer.cpp
+++ b/libs/hwui/ProfileDataContainer.cpp
@@ -16,6 +16,8 @@
 
 #include "ProfileDataContainer.h"
 
+#include <errno.h>
+
 #include <log/log.h>
 #include <cutils/ashmem.h>
 
@@ -75,4 +77,4 @@
 }
 
 } /* namespace uirenderer */
-} /* namespace android */
\ No newline at end of file
+} /* namespace android */
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp
index afb1193..f7a90b0 100644
--- a/libs/hwui/service/GraphicsStatsService.cpp
+++ b/libs/hwui/service/GraphicsStatsService.cpp
@@ -22,10 +22,11 @@
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <log/log.h>
 
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <errno.h>
 #include <fcntl.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 #include <sys/mman.h>
 
@@ -366,4 +367,4 @@
 }
 
 } /* namespace uirenderer */
-} /* namespace android */
\ No newline at end of file
+} /* namespace android */
diff --git a/libs/hwui/tests/common/TestContext.cpp b/libs/hwui/tests/common/TestContext.cpp
index c1ca1e7..1e30d23 100644
--- a/libs/hwui/tests/common/TestContext.cpp
+++ b/libs/hwui/tests/common/TestContext.cpp
@@ -81,10 +81,10 @@
     mSurfaceControl = mSurfaceComposerClient->createSurface(String8("HwuiTest"),
             gDisplay.w, gDisplay.h, PIXEL_FORMAT_RGBX_8888);
 
-    SurfaceComposerClient::openGlobalTransaction();
-    mSurfaceControl->setLayer(0x7FFFFFF);
-    mSurfaceControl->show();
-    SurfaceComposerClient::closeGlobalTransaction();
+    SurfaceComposerClient::Transaction t;
+    t.setLayer(mSurfaceControl, 0x7FFFFFF)
+            .show(mSurfaceControl)
+            .apply();
     mSurface = mSurfaceControl->getSurface();
 }
 
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index ed31b12..173cd50 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -148,8 +148,9 @@
         }
     }
 
-    // Resize sprites if needed, inside a global transaction.
-    bool haveGlobalTransaction = false;
+    // Resize sprites if needed.
+    SurfaceComposerClient::Transaction t;
+    bool needApplyTransaction = false;
     for (size_t i = 0; i < numSprites; i++) {
         SpriteUpdate& update = updates.editItemAt(i);
 
@@ -158,36 +159,24 @@
             int32_t desiredHeight = update.state.icon.bitmap.height();
             if (update.state.surfaceWidth < desiredWidth
                     || update.state.surfaceHeight < desiredHeight) {
-                if (!haveGlobalTransaction) {
-                    SurfaceComposerClient::openGlobalTransaction();
-                    haveGlobalTransaction = true;
-                }
+                needApplyTransaction = true;
 
-                status_t status = update.state.surfaceControl->setSize(desiredWidth, desiredHeight);
-                if (status) {
-                    ALOGE("Error %d resizing sprite surface from %dx%d to %dx%d",
-                            status, update.state.surfaceWidth, update.state.surfaceHeight,
-                            desiredWidth, desiredHeight);
-                } else {
-                    update.state.surfaceWidth = desiredWidth;
-                    update.state.surfaceHeight = desiredHeight;
-                    update.state.surfaceDrawn = false;
-                    update.surfaceChanged = surfaceChanged = true;
+                t.setSize(update.state.surfaceControl,
+                        desiredWidth, desiredHeight);
+                update.state.surfaceWidth = desiredWidth;
+                update.state.surfaceHeight = desiredHeight;
+                update.state.surfaceDrawn = false;
+                update.surfaceChanged = surfaceChanged = true;
 
-                    if (update.state.surfaceVisible) {
-                        status = update.state.surfaceControl->hide();
-                        if (status) {
-                            ALOGE("Error %d hiding sprite surface after resize.", status);
-                        } else {
-                            update.state.surfaceVisible = false;
-                        }
-                    }
+                if (update.state.surfaceVisible) {
+                    t.hide(update.state.surfaceControl);
+                    update.state.surfaceVisible = false;
                 }
             }
         }
     }
-    if (haveGlobalTransaction) {
-        SurfaceComposerClient::closeGlobalTransaction();
+    if (needApplyTransaction) {
+        t.apply();
     }
 
     // Redraw sprites if needed.
@@ -240,8 +229,7 @@
         }
     }
 
-    // Set sprite surface properties and make them visible.
-    bool haveTransaction = false;
+    needApplyTransaction = false;
     for (size_t i = 0; i < numSprites; i++) {
         SpriteUpdate& update = updates.editItemAt(i);
 
@@ -253,75 +241,59 @@
                 || (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA
                         | DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER
                         | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) {
-            status_t status;
-            if (!haveTransaction) {
-                SurfaceComposerClient::openGlobalTransaction();
-                haveTransaction = true;
-            }
+            needApplyTransaction = true;
 
             if (wantSurfaceVisibleAndDrawn
                     && (becomingVisible || (update.state.dirty & DIRTY_ALPHA))) {
-                status = update.state.surfaceControl->setAlpha(update.state.alpha);
-                if (status) {
-                    ALOGE("Error %d setting sprite surface alpha.", status);
-                }
+                t.setAlpha(update.state.surfaceControl,
+                        update.state.alpha);
             }
 
             if (wantSurfaceVisibleAndDrawn
                     && (becomingVisible || (update.state.dirty & (DIRTY_POSITION
                             | DIRTY_HOTSPOT)))) {
-                status = update.state.surfaceControl->setPosition(
+                t.setPosition(
+                        update.state.surfaceControl,
                         update.state.positionX - update.state.icon.hotSpotX,
                         update.state.positionY - update.state.icon.hotSpotY);
-                if (status) {
-                    ALOGE("Error %d setting sprite surface position.", status);
-                }
             }
 
             if (wantSurfaceVisibleAndDrawn
                     && (becomingVisible
                             || (update.state.dirty & DIRTY_TRANSFORMATION_MATRIX))) {
-                status = update.state.surfaceControl->setMatrix(
+                t.setMatrix(
+                        update.state.surfaceControl,
                         update.state.transformationMatrix.dsdx,
                         update.state.transformationMatrix.dtdx,
                         update.state.transformationMatrix.dsdy,
                         update.state.transformationMatrix.dtdy);
-                if (status) {
-                    ALOGE("Error %d setting sprite surface transformation matrix.", status);
-                }
             }
 
             int32_t surfaceLayer = mOverlayLayer + update.state.layer;
             if (wantSurfaceVisibleAndDrawn
                     && (becomingVisible || (update.state.dirty & DIRTY_LAYER))) {
-                status = update.state.surfaceControl->setLayer(surfaceLayer);
-                if (status) {
-                    ALOGE("Error %d setting sprite surface layer.", status);
-                }
+                t.setLayer(update.state.surfaceControl, surfaceLayer);
             }
 
             if (becomingVisible) {
-                status = update.state.surfaceControl->show();
-                if (status) {
-                    ALOGE("Error %d showing sprite surface.", status);
-                } else {
-                    update.state.surfaceVisible = true;
-                    update.surfaceChanged = surfaceChanged = true;
-                }
+                t.show(update.state.surfaceControl);
+
+                update.state.surfaceVisible = true;
+                update.surfaceChanged = surfaceChanged = true;
             } else if (becomingHidden) {
-                status = update.state.surfaceControl->hide();
-                if (status) {
-                    ALOGE("Error %d hiding sprite surface.", status);
-                } else {
-                    update.state.surfaceVisible = false;
-                    update.surfaceChanged = surfaceChanged = true;
-                }
+                t.hide(update.state.surfaceControl);
+
+                update.state.surfaceVisible = false;
+                update.surfaceChanged = surfaceChanged = true;
             }
         }
     }
 
-    if (haveTransaction) {
-        SurfaceComposerClient::closeGlobalTransaction();
+    if (needApplyTransaction) {
+        status_t status = t.apply();
+        if (status) {
+            ALOGE("Error applying Surface transaction");
+        }
     }
 
     // If any surfaces were changed, write back the new surface properties to the sprites.
diff --git a/libs/protoutil/Android.mk b/libs/protoutil/Android.mk
index a534816..2a2b087 100644
--- a/libs/protoutil/Android.mk
+++ b/libs/protoutil/Android.mk
@@ -22,15 +22,15 @@
         -Wall -Werror -Wno-missing-field-initializers -Wno-unused-variable -Wunused-parameter
 
 LOCAL_SHARED_LIBRARIES := \
-        libbinder \
+        libcutils \
         liblog \
-        libutils
 
 LOCAL_C_INCLUDES := \
         $(LOCAL_PATH)/include
 
 LOCAL_SRC_FILES := \
         src/EncodedBuffer.cpp \
+        src/ProtoOutputStream.cpp \
         src/protobuf.cpp \
 
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
diff --git a/libs/protoutil/include/android/util/EncodedBuffer.h b/libs/protoutil/include/android/util/EncodedBuffer.h
index cf09609..e568e4c 100644
--- a/libs/protoutil/include/android/util/EncodedBuffer.h
+++ b/libs/protoutil/include/android/util/EncodedBuffer.h
@@ -52,10 +52,10 @@
         size_t index() const;
         size_t offset() const;
 
-        void move(size_t amt);
-        inline void move() { move(1); };
+        Pointer* move(size_t amt);
+        inline Pointer* move() { return move(1); };
+        Pointer* rewind();
 
-        void rewind();
         Pointer copy() const;
 
     private:
@@ -88,15 +88,71 @@
     size_t currentToWrite();
 
     /**
-     * Write a varint into a vector. Return the size of the varint.
+     * Write a single byte to the buffer.
      */
-    size_t writeRawVarint(uint32_t val);
+    void writeRawByte(uint8_t val);
+
+    /**
+     * Write a varint32 into the buffer. Return the size of the varint.
+     */
+    size_t writeRawVarint32(uint32_t val);
+
+    /**
+     * Write a varint64 into the buffer. Return the size of the varint.
+     */
+    size_t writeRawVarint64(uint64_t val);
+
+    /**
+     * Write Fixed32 into the buffer.
+     */
+    void writeRawFixed32(uint32_t val);
+
+    /**
+     * Write Fixed64 into the buffer.
+     */
+    void writeRawFixed64(uint64_t val);
 
     /**
      * Write a protobuf header. Return the size of the header.
      */
     size_t writeHeader(uint32_t fieldId, uint8_t wireType);
 
+    /********************************* Edit APIs ************************************************/
+    /**
+     * Returns the edit pointer.
+     */
+    Pointer* ep();
+
+    /**
+     * Read a single byte at ep, and move ep to next byte;
+     */
+    uint8_t readRawByte();
+
+    /**
+     * Read varint starting at ep, ep will move to pos of next byte.
+     */
+    uint64_t readRawVarint();
+
+    /**
+     * Read 4 bytes starting at ep, ep will move to pos of next byte.
+     */
+    uint32_t readRawFixed32();
+
+    /**
+     * Read 8 bytes starting at ep, ep will move to pos of next byte.
+     */
+    uint64_t readRawFixed64();
+
+    /**
+     * Edit 4 bytes starting at pos.
+     */
+    void editRawFixed32(size_t pos, uint32_t val);
+
+    /**
+     * Copy _size_ bytes of data starting at __srcPos__ to wp.
+     */
+    void copy(size_t srcPos, size_t size);
+
     /********************************* Read APIs ************************************************/
     class iterator;
     friend class iterator;
@@ -141,9 +197,8 @@
 
         /**
          * Read varint from iterator, the iterator will point to next available byte.
-         * Return the number of bytes of the varint.
          */
-        uint32_t readRawVarint();
+        uint64_t readRawVarint();
 
     private:
         const EncodedBuffer& mData;
@@ -160,6 +215,7 @@
     vector<uint8_t*> mBuffers;
 
     Pointer mWp;
+    Pointer mEp;
 
     inline uint8_t* at(const Pointer& p) const; // helper function to get value
 };
@@ -167,4 +223,5 @@
 } // util
 } // android
 
-#endif // ANDROID_UTIL_ENCODED_BUFFER_H
\ No newline at end of file
+#endif // ANDROID_UTIL_ENCODED_BUFFER_H
+
diff --git a/libs/protoutil/include/android/util/ProtoOutputStream.h b/libs/protoutil/include/android/util/ProtoOutputStream.h
new file mode 100644
index 0000000..49ec169
--- /dev/null
+++ b/libs/protoutil/include/android/util/ProtoOutputStream.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H
+#define ANDROID_UTIL_PROTOOUTPUT_STREAM_H
+
+#include <android/util/EncodedBuffer.h>
+
+#include <stdint.h>
+#include <string>
+
+namespace android {
+namespace util {
+
+/**
+ * Class to write to a protobuf stream.
+ *
+ * Each write method takes an ID code from the protoc generated classes
+ * and the value to write.  To make a nested object, call start
+ * and then end when you are done.
+ *
+ * See the java version implementation (ProtoOutputStream.java) for more infos.
+ */
+class ProtoOutputStream
+{
+public:
+    ProtoOutputStream(int fd);
+    ~ProtoOutputStream();
+
+    /**
+     * Write APIs for dumping protobuf data. Returns true if the write succeeds.
+     */
+    bool write(uint64_t fieldId, double val);
+    bool write(uint64_t fieldId, float val);
+    bool write(uint64_t fieldId, int val);
+    bool write(uint64_t fieldId, long long val);
+    bool write(uint64_t fieldId, bool val);
+    bool write(uint64_t fieldId, std::string val);
+    bool write(uint64_t fieldId, const char* val);
+
+    /**
+     * Starts a sub-message write session.
+     * Returns a token of this write session.
+     * Must call end(token) when finish write this sub-message.
+     */
+    long long start(uint64_t fieldId);
+    void end(long long token);
+
+    /**
+     * Flushes the protobuf data out.
+     */
+    bool flush();
+
+private:
+    EncodedBuffer mBuffer;
+    int mFd;
+    size_t mCopyBegin;
+    bool mCompact;
+    int mDepth;
+    int mObjectId;
+    long long mExpectedObjectToken;
+
+    inline void writeDoubleImpl(uint32_t id, double val);
+    inline void writeFloatImpl(uint32_t id, float val);
+    inline void writeInt64Impl(uint32_t id, long long val);
+    inline void writeInt32Impl(uint32_t id, int val);
+    inline void writeUint64Impl(uint32_t id, uint64_t val);
+    inline void writeUint32Impl(uint32_t id, uint32_t val);
+    inline void writeFixed64Impl(uint32_t id, uint64_t val);
+    inline void writeFixed32Impl(uint32_t id, uint32_t val);
+    inline void writeSFixed64Impl(uint32_t id, long long val);
+    inline void writeSFixed32Impl(uint32_t id, int val);
+    inline void writeZigzagInt64Impl(uint32_t id, long long val);
+    inline void writeZigzagInt32Impl(uint32_t id, int val);
+    inline void writeEnumImpl(uint32_t id, int val);
+    inline void writeBoolImpl(uint32_t id, bool val);
+    inline void writeUtf8StringImpl(uint32_t id, const char* val, size_t size);
+
+    bool compact();
+    size_t editEncodedSize(size_t rawSize);
+    bool compactSize(size_t rawSize);
+};
+
+}
+}
+
+#endif // ANDROID_UTIL_PROTOOUTPUT_STREAM_H
\ No newline at end of file
diff --git a/libs/protoutil/include/android/util/protobuf.h b/libs/protoutil/include/android/util/protobuf.h
index f4e8d09..ca45e26 100644
--- a/libs/protoutil/include/android/util/protobuf.h
+++ b/libs/protoutil/include/android/util/protobuf.h
@@ -24,6 +24,9 @@
 
 using namespace std;
 
+const int FIELD_ID_SHIFT = 3;
+const uint8_t WIRE_TYPE_MASK = (1 << FIELD_ID_SHIFT) - 1;
+
 const uint8_t WIRE_TYPE_VARINT = 0;
 const uint8_t WIRE_TYPE_FIXED64 = 1;
 const uint8_t WIRE_TYPE_LENGTH_DELIMITED = 2;
@@ -35,16 +38,20 @@
 uint8_t read_wire_type(uint32_t varint);
 
 /**
- * read field id from varint, it is varint >> 3;
+ * Read field id from varint, it is varint >> 3;
  */
 uint32_t read_field_id(uint32_t varint);
 
 /**
- * Write a varint into the buffer. Return the next position to write at.
- * There must be 10 bytes in the buffer. The same as
- * EncodedBuffer.writeRawVarint32
+ * Get the size of a varint.
  */
-uint8_t* write_raw_varint(uint8_t* buf, uint32_t val);
+size_t get_varint_size(uint64_t varint);
+
+/**
+ * Write a varint into the buffer. Return the next position to write at.
+ * There must be 10 bytes in the buffer.
+ */
+uint8_t* write_raw_varint(uint8_t* buf, uint64_t val);
 
 /**
  * Write a protobuf WIRE_TYPE_LENGTH_DELIMITED header. Return the next position
diff --git a/libs/protoutil/src/EncodedBuffer.cpp b/libs/protoutil/src/EncodedBuffer.cpp
index 84dc5b6..435ae88 100644
--- a/libs/protoutil/src/EncodedBuffer.cpp
+++ b/libs/protoutil/src/EncodedBuffer.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <android/util/EncodedBuffer.h>
+#include <android/util/protobuf.h>
 
 #include <stdlib.h>
 
@@ -52,19 +53,21 @@
     return mOffset;
 }
 
-void
+EncodedBuffer::Pointer*
 EncodedBuffer::Pointer::move(size_t amt)
 {
     size_t newOffset = mOffset + amt;
     mIndex += newOffset / mChunkSize;
     mOffset = newOffset % mChunkSize;
+    return this;
 }
 
-void
+EncodedBuffer::Pointer*
 EncodedBuffer::Pointer::rewind()
 {
     mIndex = 0;
     mOffset = 0;
+    return this;
 }
 
 EncodedBuffer::Pointer
@@ -86,6 +89,7 @@
 {
     mChunkSize = chunkSize == 0 ? BUFFER_SIZE : chunkSize;
     mWp = Pointer(mChunkSize);
+    mEp = Pointer(mChunkSize);
 }
 
 EncodedBuffer::~EncodedBuffer()
@@ -137,28 +141,136 @@
     return mChunkSize - mWp.offset();
 }
 
+void
+EncodedBuffer::writeRawByte(uint8_t val)
+{
+    *writeBuffer() = val;
+    mWp.move();
+}
+
 size_t
-EncodedBuffer::writeRawVarint(uint32_t val)
+EncodedBuffer::writeRawVarint64(uint64_t val)
 {
     size_t size = 0;
     while (true) {
         size++;
         if ((val & ~0x7F) == 0) {
-            *writeBuffer() = (uint8_t) val;
-            mWp.move();
+            writeRawByte((uint8_t) val);
             return size;
         } else {
-            *writeBuffer() = (uint8_t)((val & 0x7F) | 0x80);
-            mWp.move();
+            writeRawByte((uint8_t)((val & 0x7F) | 0x80));
             val >>= 7;
         }
     }
 }
 
 size_t
+EncodedBuffer::writeRawVarint32(uint32_t val)
+{
+    uint64_t v =(uint64_t)val;
+    return writeRawVarint64(v);
+}
+
+void
+EncodedBuffer::writeRawFixed32(uint32_t val)
+{
+    writeRawByte((uint8_t) val);
+    writeRawByte((uint8_t) (val>>8));
+    writeRawByte((uint8_t) (val>>16));
+    writeRawByte((uint8_t) (val>>24));
+}
+
+void
+EncodedBuffer::writeRawFixed64(uint64_t val)
+{
+    writeRawByte((uint8_t) val);
+    writeRawByte((uint8_t) (val>>8));
+    writeRawByte((uint8_t) (val>>16));
+    writeRawByte((uint8_t) (val>>24));
+    writeRawByte((uint8_t) (val>>32));
+    writeRawByte((uint8_t) (val>>40));
+    writeRawByte((uint8_t) (val>>48));
+    writeRawByte((uint8_t) (val>>56));
+}
+
+size_t
 EncodedBuffer::writeHeader(uint32_t fieldId, uint8_t wireType)
 {
-    return writeRawVarint((fieldId << 3) | wireType);
+    return writeRawVarint32((fieldId << FIELD_ID_SHIFT) | wireType);
+}
+
+/******************************** Edit APIs ************************************************/
+EncodedBuffer::Pointer*
+EncodedBuffer::ep()
+{
+    return &mEp;
+}
+
+uint8_t
+EncodedBuffer::readRawByte()
+{
+    uint8_t val = *at(mEp);
+    mEp.move();
+    return val;
+}
+
+uint64_t
+EncodedBuffer::readRawVarint()
+{
+    uint64_t val = 0, shift = 0;
+    size_t start = mEp.pos();
+    while (true) {
+        uint8_t byte = readRawByte();
+        val += (byte & 0x7F) << shift;
+        if ((byte & 0x80) == 0) break;
+        shift += 7;
+    }
+    return val;
+}
+
+uint32_t
+EncodedBuffer::readRawFixed32()
+{
+    uint32_t val = 0;
+    for (auto i=0; i<32; i+=8) {
+        val += (uint32_t)readRawByte() << i;
+    }
+    return val;
+}
+
+uint64_t
+EncodedBuffer::readRawFixed64()
+{
+    uint64_t val = 0;
+    for (auto i=0; i<64; i+=8) {
+        val += (uint64_t)readRawByte() << i;
+    }
+    return val;
+}
+
+void
+EncodedBuffer::editRawFixed32(size_t pos, uint32_t val)
+{
+    size_t oldPos = mEp.pos();
+    mEp.rewind()->move(pos);
+    for (auto i=0; i<32; i+=8) {
+        *at(mEp) = (uint8_t) (val >> i);
+        mEp.move();
+    }
+    mEp.rewind()->move(oldPos);
+}
+
+void
+EncodedBuffer::copy(size_t srcPos, size_t size)
+{
+    if (size == 0) return;
+    Pointer cp(mChunkSize);
+    cp.move(srcPos);
+
+    while (cp.pos() < srcPos + size) {
+        writeRawByte(*at(cp));
+        cp.move();
+    }
 }
 
 /********************************* Read APIs ************************************************/
@@ -220,10 +332,10 @@
     return res;
 }
 
-uint32_t
+uint64_t
 EncodedBuffer::iterator::readRawVarint()
 {
-    uint32_t val = 0, shift = 0;
+    uint64_t val = 0, shift = 0;
     while (true) {
         uint8_t byte = next();
         val += (byte & 0x7F) << shift;
diff --git a/libs/protoutil/src/ProtoOutputStream.cpp b/libs/protoutil/src/ProtoOutputStream.cpp
new file mode 100644
index 0000000..e9ca0dc
--- /dev/null
+++ b/libs/protoutil/src/ProtoOutputStream.cpp
@@ -0,0 +1,652 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+#define LOG_TAG "libprotoutil"
+
+#include <android/util/protobuf.h>
+#include <android/util/ProtoOutputStream.h>
+#include <cutils/log.h>
+#include <cstring>
+
+namespace android {
+namespace util {
+
+/**
+ * Position of the field type in a (long long) fieldId.
+ */
+const uint64_t FIELD_TYPE_SHIFT = 32;
+
+/**
+ * Mask for the field types stored in a fieldId.  Leaves a whole
+ * byte for future expansion, even though there are currently only 17 types.
+ */
+const uint64_t FIELD_TYPE_MASK = 0x0ffULL << FIELD_TYPE_SHIFT;
+
+const uint64_t FIELD_TYPE_UNKNOWN  = 0;
+const uint64_t TYPE_DOUBLE         = 1ULL << FIELD_TYPE_SHIFT;   // double, exactly eight bytes on the wire.
+const uint64_t TYPE_FLOAT          = 2ULL << FIELD_TYPE_SHIFT;   // float, exactly four bytes on the wire.
+const uint64_t TYPE_INT64          = 3ULL << FIELD_TYPE_SHIFT;   // int64, varint on the wire.  Negative numbers
+                                                                 // take 10 bytes.  Use TYPE_SINT64 if negative
+                                                                 // values are likely.
+const uint64_t TYPE_UINT64         = 4ULL << FIELD_TYPE_SHIFT;   // uint64, varint on the wire.
+const uint64_t TYPE_INT32          = 5ULL << FIELD_TYPE_SHIFT;   // int32, varint on the wire.  Negative numbers
+                                                                 // take 10 bytes.  Use TYPE_SINT32 if negative
+                                                                 // values are likely.
+const uint64_t TYPE_FIXED64        = 6ULL << FIELD_TYPE_SHIFT;   // uint64, exactly eight bytes on the wire.
+const uint64_t TYPE_FIXED32        = 7ULL << FIELD_TYPE_SHIFT;   // uint32, exactly four bytes on the wire.
+const uint64_t TYPE_BOOL           = 8ULL << FIELD_TYPE_SHIFT;   // bool, varint on the wire.
+const uint64_t TYPE_STRING         = 9ULL << FIELD_TYPE_SHIFT;   // UTF-8 text.
+const uint64_t TYPE_GROUP          = 10ULL << FIELD_TYPE_SHIFT;  // Tag-delimited message.  Deprecated.
+const uint64_t TYPE_MESSAGE        = 11ULL << FIELD_TYPE_SHIFT;  // Length-delimited message.
+
+const uint64_t TYPE_BYTES          = 12ULL << FIELD_TYPE_SHIFT;  // Arbitrary byte array.
+const uint64_t TYPE_UINT32         = 13ULL << FIELD_TYPE_SHIFT;  // uint32, varint on the wire
+const uint64_t TYPE_ENUM           = 14ULL << FIELD_TYPE_SHIFT;  // Enum, varint on the wire
+const uint64_t TYPE_SFIXED32       = 15ULL << FIELD_TYPE_SHIFT;  // int32, exactly four bytes on the wire
+const uint64_t TYPE_SFIXED64       = 16ULL << FIELD_TYPE_SHIFT;  // int64, exactly eight bytes on the wire
+const uint64_t TYPE_SINT32         = 17ULL << FIELD_TYPE_SHIFT;  // int32, ZigZag-encoded varint on the wire
+const uint64_t TYPE_SINT64         = 18ULL << FIELD_TYPE_SHIFT;  // int64, ZigZag-encoded varint on the wire
+
+//
+// FieldId flags for whether the field is single, repeated or packed.
+// TODO: packed is not supported yet.
+//
+const uint64_t FIELD_COUNT_SHIFT = 40;
+const uint64_t FIELD_COUNT_MASK = 0x0fULL << FIELD_COUNT_SHIFT;
+const uint64_t FIELD_COUNT_UNKNOWN = 0;
+const uint64_t FIELD_COUNT_SINGLE = 1ULL << FIELD_COUNT_SHIFT;
+const uint64_t FIELD_COUNT_REPEATED = 2ULL << FIELD_COUNT_SHIFT;
+const uint64_t FIELD_COUNT_PACKED = 4ULL << FIELD_COUNT_SHIFT;
+
+ProtoOutputStream::ProtoOutputStream(int fd)
+        :mBuffer(),
+         mFd(fd),
+         mCopyBegin(0),
+         mCompact(false),
+         mDepth(0),
+         mObjectId(0),
+         mExpectedObjectToken(0LL)
+{
+}
+
+ProtoOutputStream::~ProtoOutputStream()
+{
+}
+
+bool
+ProtoOutputStream::write(uint64_t fieldId, double val)
+{
+    if (mCompact) return false;
+    const uint32_t id = (uint32_t)fieldId;
+    switch (fieldId & FIELD_TYPE_MASK) {
+        case TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
+        case TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
+        case TYPE_INT64:    writeInt64Impl(id, (long long)val);         break;
+        case TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
+        case TYPE_INT32:    writeInt32Impl(id, (int)val);               break;
+        case TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
+        case TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
+        case TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
+        case TYPE_SFIXED32: writeSFixed32Impl(id, (int)val);            break;
+        case TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val);      break;
+        case TYPE_SINT32:   writeZigzagInt32Impl(id, (int)val);         break;
+        case TYPE_SINT64:   writeZigzagInt64Impl(id, (long long)val);   break;
+        default:
+            ALOGW("Field type %d is not supported when writing double val.",
+                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            return false;
+    }
+    return true;
+}
+
+bool
+ProtoOutputStream::write(uint64_t fieldId, float val)
+{
+    if (mCompact) return false;
+    const uint32_t id = (uint32_t)fieldId;
+    switch (fieldId & FIELD_TYPE_MASK) {
+        case TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
+        case TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
+        case TYPE_INT64:    writeInt64Impl(id, (long long)val);         break;
+        case TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
+        case TYPE_INT32:    writeInt32Impl(id, (int)val);               break;
+        case TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
+        case TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
+        case TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
+        case TYPE_SFIXED32: writeSFixed32Impl(id, (int)val);            break;
+        case TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val);      break;
+        case TYPE_SINT32:   writeZigzagInt32Impl(id, (int)val);         break;
+        case TYPE_SINT64:   writeZigzagInt64Impl(id, (long long)val);   break;
+        default:
+            ALOGW("Field type %d is not supported when writing float val.",
+                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            return false;
+    }
+    return true;
+}
+
+bool
+ProtoOutputStream::write(uint64_t fieldId, int val)
+{
+    if (mCompact) return false;
+    const uint32_t id = (uint32_t)fieldId;
+    switch (fieldId & FIELD_TYPE_MASK) {
+        case TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
+        case TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
+        case TYPE_INT64:    writeInt64Impl(id, (long long)val);         break;
+        case TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
+        case TYPE_INT32:    writeInt32Impl(id, (int)val);               break;
+        case TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
+        case TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
+        case TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
+        case TYPE_SFIXED32: writeSFixed32Impl(id, (int)val);            break;
+        case TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val);      break;
+        case TYPE_SINT32:   writeZigzagInt32Impl(id, (int)val);         break;
+        case TYPE_SINT64:   writeZigzagInt64Impl(id, (long long)val);   break;
+        case TYPE_ENUM:     writeEnumImpl(id, (int)val);                break;
+        case TYPE_BOOL:     writeBoolImpl(id, val != 0);                break;
+        default:
+            ALOGW("Field type %d is not supported when writing int val.",
+                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            return false;
+    }
+    return true;
+}
+
+bool
+ProtoOutputStream::write(uint64_t fieldId, long long val)
+{
+    if (mCompact) return false;
+    const uint32_t id = (uint32_t)fieldId;
+    switch (fieldId & FIELD_TYPE_MASK) {
+        case TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
+        case TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
+        case TYPE_INT64:    writeInt64Impl(id, (long long)val);         break;
+        case TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
+        case TYPE_INT32:    writeInt32Impl(id, (int)val);               break;
+        case TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
+        case TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
+        case TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
+        case TYPE_SFIXED32: writeSFixed32Impl(id, (int)val);            break;
+        case TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val);      break;
+        case TYPE_SINT32:   writeZigzagInt32Impl(id, (int)val);         break;
+        case TYPE_SINT64:   writeZigzagInt64Impl(id, (long long)val);   break;
+        case TYPE_ENUM:     writeEnumImpl(id, (int)val);                break;
+        case TYPE_BOOL:     writeBoolImpl(id, val != 0);                break;
+        default:
+            ALOGW("Field type %d is not supported when writing long long val.",
+                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            return false;
+    }
+    return true;
+}
+
+bool
+ProtoOutputStream::write(uint64_t fieldId, bool val)
+{
+    if (mCompact) return false;
+    const uint32_t id = (uint32_t)fieldId;
+    switch (fieldId & FIELD_TYPE_MASK) {
+        case TYPE_BOOL:
+            writeBoolImpl(id, val);
+            return true;
+        default:
+            ALOGW("Field type %d is not supported when writing bool val.",
+                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            return false;
+    }
+}
+
+bool
+ProtoOutputStream::write(uint64_t fieldId, string val)
+{
+    if (mCompact) return false;
+    const uint32_t id = (uint32_t)fieldId;
+    switch (fieldId & FIELD_TYPE_MASK) {
+        case TYPE_STRING:
+            writeUtf8StringImpl(id, val.c_str(), val.size());
+            return true;
+        default:
+            ALOGW("Field type %d is not supported when writing string val.",
+                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            return false;
+    }
+}
+
+bool
+ProtoOutputStream::write(uint64_t fieldId, const char* val)
+{
+    if (mCompact) return false;
+    const uint32_t id = (uint32_t)fieldId;
+    int size = 0;
+    while (val[size] != '\0') size++;
+    switch (fieldId & FIELD_TYPE_MASK) {
+        case TYPE_STRING:
+            writeUtf8StringImpl(id, val, size);
+            return true;
+        default:
+            ALOGW("Field type %d is not supported when writing char[] val.",
+                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            return false;
+    }
+}
+
+/**
+ * Make a token.
+ *  Bits 61-63 - tag size (So we can go backwards later if the object had not data)
+ *                - 3 bits, max value 7, max value needed 5
+ *  Bit  60    - true if the object is repeated
+ *  Bits 59-51 - depth (For error checking)
+ *                - 9 bits, max value 512, when checking, value is masked (if we really
+ *                  are more than 512 levels deep)
+ *  Bits 32-50 - objectId (For error checking)
+ *                - 19 bits, max value 524,288. that's a lot of objects. IDs will wrap
+ *                  because of the overflow, and only the tokens are compared.
+ *  Bits  0-31 - offset of the first size field in the buffer.
+ */
+long long
+makeToken(int tagSize, bool repeated, int depth, int objectId, int sizePos) {
+    return ((0x07L & (long long)tagSize) << 61)
+            | (repeated ? (1LL << 60) : 0)
+            | (0x01ffL & (long long)depth) << 51
+            | (0x07ffffL & (long long)objectId) << 32
+            | (0x0ffffffffL & (long long)sizePos);
+}
+
+/**
+ * Get the encoded tag size from the token.
+ */
+static int getTagSizeFromToken(long long token) {
+    return (int)(0x7 & (token >> 61));
+}
+
+/**
+ * Get the nesting depth of startObject calls from the token.
+ */
+static int getDepthFromToken(long long token) {
+    return (int)(0x01ff & (token >> 51));
+}
+
+/**
+ * Get the location of the childRawSize (the first 32 bit size field) in this object.
+ */
+static int getSizePosFromToken(long long token) {
+    return (int)token;
+}
+
+long long
+ProtoOutputStream::start(uint64_t fieldId)
+{
+    if ((fieldId & FIELD_TYPE_MASK) != TYPE_MESSAGE) {
+        ALOGE("Can't call start for non-message type field: 0x%llx", (long long)fieldId);
+        return 0;
+    }
+
+    uint32_t id = (uint32_t)fieldId;
+    mBuffer.writeHeader(id, WIRE_TYPE_LENGTH_DELIMITED);
+
+    size_t sizePos = mBuffer.wp()->pos();
+
+    mDepth++;
+    mObjectId++;
+    mBuffer.writeRawFixed64(mExpectedObjectToken); // push previous token into stack.
+
+    mExpectedObjectToken = makeToken(get_varint_size(id),
+        (bool)(fieldId & FIELD_COUNT_REPEATED), mDepth, mObjectId, sizePos);
+    return mExpectedObjectToken;
+}
+
+void
+ProtoOutputStream::end(long long token)
+{
+    if (token != mExpectedObjectToken) {
+        ALOGE("Unexpected token: 0x%llx, should be 0x%llx", token, mExpectedObjectToken);
+        return;
+    }
+
+    int depth = getDepthFromToken(token);
+    if (depth != (mDepth & 0x01ff)) {
+        ALOGE("Unexpected depth: %d, should be %d", depth, mDepth);
+        return;
+    }
+    mDepth--;
+
+    int sizePos = getSizePosFromToken(token);
+    // number of bytes written in this start-end session.
+    int childRawSize = mBuffer.wp()->pos() - sizePos - 8;
+
+    // retrieve the old token from stack.
+    mBuffer.ep()->rewind()->move(sizePos);
+    mExpectedObjectToken = mBuffer.readRawFixed64();
+
+    // If raw size is larger than 0, write the negative value here to indicate a compact is needed.
+    if (childRawSize > 0) {
+        mBuffer.editRawFixed32(sizePos, -childRawSize);
+        mBuffer.editRawFixed32(sizePos+4, -1);
+    } else {
+        // reset wp which erase the header tag of the message when its size is 0.
+        mBuffer.wp()->rewind()->move(sizePos - getTagSizeFromToken(token));
+    }
+}
+
+bool
+ProtoOutputStream::compact() {
+    if (mCompact) return true;
+    if (mDepth != 0) {
+        ALOGE("Can't compact when depth(%d) is not zero. Missing calls to end.", mDepth);
+        return false;
+    }
+    // record the size of the original buffer.
+    size_t rawBufferSize = mBuffer.size();
+    if (rawBufferSize == 0) return true; // nothing to do if the buffer is empty;
+
+    // reset edit pointer and recursively compute encoded size of messages.
+    mBuffer.ep()->rewind();
+    if (editEncodedSize(rawBufferSize) == 0) {
+        ALOGE("Failed to editEncodedSize.");
+        return false;
+    }
+
+    // reset both edit pointer and write pointer, and compact recursively.
+    mBuffer.ep()->rewind();
+    mBuffer.wp()->rewind();
+    if (!compactSize(rawBufferSize)) {
+        ALOGE("Failed to compactSize.");
+        return false;
+    }
+    // copy the reset to the buffer.
+    if (mCopyBegin < rawBufferSize) {
+        mBuffer.copy(mCopyBegin, rawBufferSize - mCopyBegin);
+    }
+
+    // mark true means it is not legal to write to this ProtoOutputStream anymore
+    mCompact = true;
+    return true;
+}
+
+/**
+ * First compaction pass.  Iterate through the data, and fill in the
+ * nested object sizes so the next pass can compact them.
+ */
+size_t
+ProtoOutputStream::editEncodedSize(size_t rawSize)
+{
+    size_t objectStart = mBuffer.ep()->pos();
+    size_t objectEnd = objectStart + rawSize;
+    size_t encodedSize = 0;
+    int childRawSize, childEncodedSize;
+    size_t childEncodedSizePos;
+
+    while (mBuffer.ep()->pos() < objectEnd) {
+        uint32_t tag = (uint32_t)mBuffer.readRawVarint();
+        encodedSize += get_varint_size(tag);
+        switch (read_wire_type(tag)) {
+            case WIRE_TYPE_VARINT:
+                do {
+                    encodedSize++;
+                } while ((mBuffer.readRawByte() & 0x80) != 0);
+                break;
+            case WIRE_TYPE_FIXED64:
+                encodedSize += 8;
+                mBuffer.ep()->move(8);
+                break;
+            case WIRE_TYPE_LENGTH_DELIMITED:
+                childRawSize = (int)mBuffer.readRawFixed32();
+                childEncodedSizePos = mBuffer.ep()->pos();
+                childEncodedSize = (int)mBuffer.readRawFixed32();
+                if (childRawSize >= 0 && childRawSize == childEncodedSize) {
+                    mBuffer.ep()->move(childRawSize);
+                } else if (childRawSize < 0 && childEncodedSize == -1){
+                    childEncodedSize = editEncodedSize(-childRawSize);
+                    mBuffer.editRawFixed32(childEncodedSizePos, childEncodedSize);
+                } else {
+                    ALOGE("Bad raw or encoded values: raw=%d, encoded=%d at %zu",
+                            childRawSize, childEncodedSize, childEncodedSizePos);
+                    return 0;
+                }
+                encodedSize += get_varint_size(childEncodedSize) + childEncodedSize;
+                break;
+            case WIRE_TYPE_FIXED32:
+                encodedSize += 4;
+                mBuffer.ep()->move(4);
+                break;
+            default:
+                ALOGE("Unexpected wire type %d in editEncodedSize at [%zu, %zu]",
+                        read_wire_type(tag), objectStart, objectEnd);
+                return 0;
+        }
+    }
+    return encodedSize;
+}
+
+/**
+ * Second compaction pass.  Iterate through the data, and copy the data
+ * forward in the buffer, converting the pairs of uint32s into a single
+ * unsigned varint of the size.
+ */
+bool
+ProtoOutputStream::compactSize(size_t rawSize)
+{
+    size_t objectStart = mBuffer.ep()->pos();
+    size_t objectEnd = objectStart + rawSize;
+    int childRawSize, childEncodedSize;
+
+    while (mBuffer.ep()->pos() < objectEnd) {
+        uint32_t tag = (uint32_t)mBuffer.readRawVarint();
+        switch (read_wire_type(tag)) {
+            case WIRE_TYPE_VARINT:
+                while ((mBuffer.readRawByte() & 0x80) != 0) {}
+                break;
+            case WIRE_TYPE_FIXED64:
+                mBuffer.ep()->move(8);
+                break;
+            case WIRE_TYPE_LENGTH_DELIMITED:
+                mBuffer.copy(mCopyBegin, mBuffer.ep()->pos() - mCopyBegin);
+
+                childRawSize = (int)mBuffer.readRawFixed32();
+                childEncodedSize = (int)mBuffer.readRawFixed32();
+                mCopyBegin = mBuffer.ep()->pos();
+
+                // write encoded size to buffer.
+                mBuffer.writeRawVarint32(childEncodedSize);
+                if (childRawSize >= 0 && childRawSize == childEncodedSize) {
+                    mBuffer.ep()->move(childEncodedSize);
+                } else if (childRawSize < 0){
+                    if (!compactSize(-childRawSize)) return false;
+                } else {
+                    ALOGE("Bad raw or encoded values: raw=%d, encoded=%d",
+                            childRawSize, childEncodedSize);
+                    return false;
+                }
+                break;
+            case WIRE_TYPE_FIXED32:
+                mBuffer.ep()->move(4);
+                break;
+            default:
+                ALOGE("Unexpected wire type %d in compactSize at [%zu, %zu]",
+                        read_wire_type(tag), objectStart, objectEnd);
+                return false;
+        }
+    }
+    return true;
+}
+
+static bool write_all(int fd, uint8_t const* buf, size_t size)
+{
+    while (size > 0) {
+        ssize_t amt = ::write(fd, buf, size);
+        if (amt < 0) {
+            return false;
+        }
+        size -= amt;
+        buf += amt;
+    }
+    return true;
+}
+
+bool
+ProtoOutputStream::flush()
+{
+    if (mFd < 0) return false;
+    if (!compact()) return false;
+
+    EncodedBuffer::iterator it = mBuffer.begin();
+    while (it.readBuffer() != NULL) {
+        if (!write_all(mFd, it.readBuffer(), it.currentToRead())) return false;
+        it.rp()->move(it.currentToRead());
+    }
+    return true;
+}
+
+
+// =========================================================================
+// Private functions
+
+/**
+ * bit_cast
+ */
+template <class From, class To>
+inline To bit_cast(From const &from) {
+    To to;
+    memcpy(&to, &from, sizeof(to));
+    return to;
+}
+
+inline void
+ProtoOutputStream::writeDoubleImpl(uint32_t id, double val)
+{
+    if (val == 0.0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
+    mBuffer.writeRawFixed64(bit_cast<double, uint64_t>(val));
+}
+
+inline void
+ProtoOutputStream::writeFloatImpl(uint32_t id, float val)
+{
+    if (val == 0.0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
+    mBuffer.writeRawFixed32(bit_cast<float, uint32_t>(val));
+}
+
+inline void
+ProtoOutputStream::writeInt64Impl(uint32_t id, long long val)
+{
+    if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer.writeRawVarint64((uint64_t)val);
+}
+
+inline void
+ProtoOutputStream::writeInt32Impl(uint32_t id, int val)
+{
+    if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer.writeRawVarint32((uint32_t)val);
+}
+
+inline void
+ProtoOutputStream::writeUint64Impl(uint32_t id, uint64_t val)
+{
+   if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer.writeRawVarint64(val);
+}
+
+inline void
+ProtoOutputStream::writeUint32Impl(uint32_t id, uint32_t val)
+{
+    if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer.writeRawVarint32(val);
+}
+
+inline void
+ProtoOutputStream::writeFixed64Impl(uint32_t id, uint64_t val)
+{
+    if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
+    mBuffer.writeRawFixed64(val);
+}
+
+inline void
+ProtoOutputStream::writeFixed32Impl(uint32_t id, uint32_t val)
+{
+    if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
+    mBuffer.writeRawFixed32(val);
+}
+
+inline void
+ProtoOutputStream::writeSFixed64Impl(uint32_t id, long long val)
+{
+    if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
+    mBuffer.writeRawFixed64((uint64_t)val);
+}
+
+inline void
+ProtoOutputStream::writeSFixed32Impl(uint32_t id, int val)
+{
+    if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
+    mBuffer.writeRawFixed32((uint32_t)val);
+}
+
+inline void
+ProtoOutputStream::writeZigzagInt64Impl(uint32_t id, long long val)
+{
+    if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer.writeRawVarint64((val << 1) ^ (val >> 63));
+}
+
+inline void
+ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int val)
+{
+    if (val == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer.writeRawVarint32((val << 1) ^ (val >> 31));
+}
+
+inline void
+ProtoOutputStream::writeEnumImpl(uint32_t id, int val)
+{
+    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer.writeRawVarint32((uint32_t) val);
+}
+
+inline void
+ProtoOutputStream::writeBoolImpl(uint32_t id, bool val)
+{
+    if (!val) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer.writeRawVarint32(val ? 1 : 0);
+}
+
+inline void
+ProtoOutputStream::writeUtf8StringImpl(uint32_t id, const char* val, size_t size)
+{
+    if (val == NULL || size == 0) return;
+    mBuffer.writeHeader(id, WIRE_TYPE_LENGTH_DELIMITED);
+    mBuffer.writeRawFixed32(size);
+    mBuffer.writeRawFixed32(size);
+    for (size_t i=0; i<size; i++) {
+        mBuffer.writeRawByte((uint8_t)val[i]);
+    }
+}
+
+} // util
+} // android
+
diff --git a/libs/protoutil/src/protobuf.cpp b/libs/protoutil/src/protobuf.cpp
index ec5325c..1c7eef9 100644
--- a/libs/protoutil/src/protobuf.cpp
+++ b/libs/protoutil/src/protobuf.cpp
@@ -22,17 +22,28 @@
 uint8_t
 read_wire_type(uint32_t varint)
 {
-    return (uint8_t) (varint & 0x07);
+    return (uint8_t) (varint & WIRE_TYPE_MASK);
 }
 
 uint32_t
 read_field_id(uint32_t varint)
 {
-    return varint >> 3;
+    return varint >> FIELD_ID_SHIFT;
+}
+
+size_t
+get_varint_size(uint64_t varint)
+{
+    size_t size = 1;
+    while ((varint & ~0x7F)) {
+        size++;
+        varint >>= 7;
+    }
+    return size;
 }
 
 uint8_t*
-write_raw_varint(uint8_t* buf, uint32_t val)
+write_raw_varint(uint8_t* buf, uint64_t val)
 {
     uint8_t* p = buf;
     while (true) {
@@ -49,7 +60,7 @@
 uint8_t*
 write_length_delimited_tag_header(uint8_t* buf, uint32_t fieldId, size_t size)
 {
-    buf = write_raw_varint(buf, (fieldId << 3) | 2);
+    buf = write_raw_varint(buf, (fieldId << FIELD_ID_SHIFT) | WIRE_TYPE_LENGTH_DELIMITED);
     buf = write_raw_varint(buf, size);
     return buf;
 }
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 26ead3d..20405d3 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -202,6 +202,22 @@
      * @see #SUPPRESSIBLE_USAGES
      */
     public final static int SUPPRESSIBLE_NEVER = 3;
+    /**
+     * @hide
+     * Denotes a usage for alarms,
+     * will be muted when the Zen mode doesn't allow alarms
+     * @see #SUPPRESSIBLE_USAGES
+     */
+    public final static int SUPPRESSIBLE_ALARM = 4;
+    /**
+     * @hide
+     * Denotes a usage for all other sounds not caught in SUPPRESSIBLE_NOTIFICATION,
+     * SUPPRESSIBLE_CALL,SUPPRESSIBLE_NEVER or SUPPRESSIBLE_ALARM.
+     * This includes media, system, game, navigation, the assistant, and more.
+     * These will be muted when the Zen mode doesn't allow media/system/other.
+     * @see #SUPPRESSIBLE_USAGES
+     */
+    public final static int SUPPRESSIBLE_MEDIA_SYSTEM_OTHER = 5;
 
     /**
      * @hide
@@ -221,6 +237,13 @@
         SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_EVENT,                SUPPRESSIBLE_NOTIFICATION);
         SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_ACCESSIBILITY,          SUPPRESSIBLE_NEVER);
         SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION,               SUPPRESSIBLE_NEVER);
+        SUPPRESSIBLE_USAGES.put(USAGE_ALARM,                             SUPPRESSIBLE_ALARM);
+        SUPPRESSIBLE_USAGES.put(USAGE_MEDIA,                             SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
+        SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_SONIFICATION,           SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
+        SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,    SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
+        SUPPRESSIBLE_USAGES.put(USAGE_GAME,                              SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
+        SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION_SIGNALLING,    SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
+        SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANT,                         SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
     }
 
     /**
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 59a124f..7678490 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -917,7 +917,7 @@
      */
     public void setNextOutputFile(File file) throws IOException
     {
-        RandomAccessFile f = new RandomAccessFile(file, "rws");
+        RandomAccessFile f = new RandomAccessFile(file, "rw");
         try {
             _setNextOutputFile(f.getFD());
         } finally {
@@ -942,7 +942,7 @@
     public void prepare() throws IllegalStateException, IOException
     {
         if (mPath != null) {
-            RandomAccessFile file = new RandomAccessFile(mPath, "rws");
+            RandomAccessFile file = new RandomAccessFile(mPath, "rw");
             try {
                 _setOutputFile(file.getFD());
             } finally {
@@ -951,7 +951,7 @@
         } else if (mFd != null) {
             _setOutputFile(mFd);
         } else if (mFile != null) {
-            RandomAccessFile file = new RandomAccessFile(mFile, "rws");
+            RandomAccessFile file = new RandomAccessFile(mFile, "rw");
             try {
                 _setOutputFile(file.getFD());
             } finally {
diff --git a/media/java/android/media/tv/ITvInputHardware.aidl b/media/java/android/media/tv/ITvInputHardware.aidl
index 96223ba..94c1013 100644
--- a/media/java/android/media/tv/ITvInputHardware.aidl
+++ b/media/java/android/media/tv/ITvInputHardware.aidl
@@ -40,12 +40,6 @@
     void setStreamVolume(float volume);
 
     /**
-     * Dispatch key event to HDMI service. The events would be automatically converted to
-     * HDMI CEC commands. If the hardware is not representing an HDMI port, this method will fail.
-     */
-    boolean dispatchKeyEventToHdmi(in KeyEvent event);
-
-    /**
      * Override default audio sink from audio policy. When override is on, it is
      * TvInputService's responsibility to adjust to audio configuration change
      * (for example, when the audio sink becomes unavailable or more desirable
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index d7a9ede..fd1f2cf 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -2590,12 +2590,9 @@
             }
         }
 
+        /** @removed */
         public boolean dispatchKeyEventToHdmi(KeyEvent event) {
-            try {
-                return mInterface.dispatchKeyEventToHdmi(event);
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+            return false;
         }
 
         public void overrideAudioSink(int audioType, String audioAddress, int samplingRate,
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 7f6980d..28827e6 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -24,7 +24,7 @@
 #include <media/IMediaHTTPService.h>
 #include <media/MediaPlayerInterface.h>
 #include <media/MediaAnalyticsItem.h>
-#include <media/stagefright/Utils.h>            // for FOURCC definition
+#include <media/stagefright/foundation/ByteUtils.h>  // for FOURCC definition
 #include <stdio.h>
 #include <assert.h>
 #include <limits.h>
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index d456950..0704e35 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -12,6 +12,32 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+cc_library_shared {
+    name: "libjnigraphics",
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wunused",
+        "-Wunreachable-code",
+    ],
+
+    // our source files
+    //
+    srcs: ["bitmap.cpp"],
+
+    shared_libs: [
+        "libandroid_runtime",
+    ],
+
+    arch: {
+        arm: {
+            // TODO: This is to work around b/24465209. Remove after root cause is fixed
+            ldflags: ["-Wl,--hash-style=both"],
+        },
+    },
+}
+
 // The headers module is in frameworks/native/Android.bp.
 ndk_library {
     name: "libjnigraphics",
diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk
deleted file mode 100644
index 7a40e62..0000000
--- a/native/graphics/jni/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-BASE_PATH := $(call my-dir)
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# setup for skia optimizations
-#
-ifneq ($(ARCH_ARM_HAVE_VFP),true)
-    LOCAL_CFLAGS += -DSK_SOFTWARE_FLOAT
-endif
-
-ifeq ($(ARCH_ARM_HAVE_NEON),true)
-    LOCAL_CFLAGS += -D__ARM_HAVE_NEON
-endif
-
-# our source files
-#
-LOCAL_SRC_FILES:= \
-    bitmap.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libandroid_runtime \
-    libui \
-    libandroidfw
-
-LOCAL_C_INCLUDES += \
-    frameworks/base/core/jni/android/graphics
-
-LOCAL_MODULE:= libjnigraphics
-
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-
-# TODO: This is to work around b/24465209. Remove after root cause is fixed
-LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index bf5cabb..ff14832 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -15,7 +15,7 @@
  */
 
 #include <android/bitmap.h>
-#include <Bitmap.h>
+#include <android/graphics/Bitmap.h>
 
 int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
                           AndroidBitmapInfo* info) {
@@ -56,4 +56,3 @@
     }
     return ANDROID_BITMAP_RESULT_SUCCESS;
 }
-
diff --git a/packages/CtsShim/build/Android.mk b/packages/CtsShim/build/Android.mk
index 21f0afe..ec14d50 100644
--- a/packages/CtsShim/build/Android.mk
+++ b/packages/CtsShim/build/Android.mk
@@ -32,6 +32,9 @@
 
 LOCAL_MANIFEST_FILE := shim_priv_upgrade/AndroidManifest.xml
 
+LOCAL_MULTILIB := both
+LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
+
 include $(BUILD_PACKAGE)
 my_shim_priv_upgrade_apk := $(LOCAL_BUILT_MODULE)
 
@@ -60,6 +63,9 @@
 
 LOCAL_FULL_MANIFEST_FILE := $(gen)
 
+LOCAL_MULTILIB := both
+LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
+
 include $(BUILD_PACKAGE)
 
 ###########################################################
@@ -80,6 +86,9 @@
 
 LOCAL_MANIFEST_FILE := shim_priv_upgrade/AndroidManifest.xml
 
+LOCAL_MULTILIB := both
+LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
+
 include $(BUILD_PACKAGE)
 
 
@@ -99,3 +108,5 @@
 
 include $(BUILD_PACKAGE)
 
+###########################################################
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/CtsShim/build/jni/Android.mk b/packages/CtsShim/build/jni/Android.mk
new file mode 100644
index 0000000..968fc0b
--- /dev/null
+++ b/packages/CtsShim/build/jni/Android.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2017 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libshim_jni
+
+LOCAL_SRC_FILES := Shim.c
+
+LOCAL_SDK_VERSION := 24
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DebugFlagsChangedEvent.java b/packages/CtsShim/build/jni/Shim.c
similarity index 64%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/DebugFlagsChangedEvent.java
copy to packages/CtsShim/build/jni/Shim.c
index fe3bf26..44eb316 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DebugFlagsChangedEvent.java
+++ b/packages/CtsShim/build/jni/Shim.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -14,13 +14,4 @@
  * limitations under the License.
  */
 
-package com.android.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the SystemUI tuner changes a flag.
- */
-public class DebugFlagsChangedEvent extends EventBus.Event {
-    // Simple event
-}
+#include <jni.h>
\ No newline at end of file
diff --git a/packages/CtsShim/build/shim_priv/AndroidManifest.xml b/packages/CtsShim/build/shim_priv/AndroidManifest.xml
index 5195ef7..9bf454c 100644
--- a/packages/CtsShim/build/shim_priv/AndroidManifest.xml
+++ b/packages/CtsShim/build/shim_priv/AndroidManifest.xml
@@ -27,6 +27,7 @@
 
     <application
         android:hasCode="false"
+        android:multiArch="true"
         tools:ignore="AllowBackup,MissingApplicationIcon" >
 
         <!-- These activities don't actually exist; define them just to test the filters !-->
diff --git a/packages/CtsShim/build/shim_priv_upgrade/AndroidManifest.xml b/packages/CtsShim/build/shim_priv_upgrade/AndroidManifest.xml
index b938e3e..023e93e 100644
--- a/packages/CtsShim/build/shim_priv_upgrade/AndroidManifest.xml
+++ b/packages/CtsShim/build/shim_priv_upgrade/AndroidManifest.xml
@@ -24,6 +24,7 @@
 
     <application
         android:hasCode="false"
+        android:multiArch="true"
         tools:ignore="AllowBackup,MissingApplicationIcon" >
 
         <!-- These activities don't actually exist; define them just to test the filters !-->
diff --git a/packages/PrintSpooler/tests/outofprocess/Android.mk b/packages/PrintSpooler/tests/outofprocess/Android.mk
index 3c02453..149be74 100644
--- a/packages/PrintSpooler/tests/outofprocess/Android.mk
+++ b/packages/PrintSpooler/tests/outofprocess/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ub-uiautomator mockito-target-minus-junit4
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ub-uiautomator mockito-target-minus-junit4 print-test-util-lib
 
 LOCAL_PACKAGE_NAME := PrintSpoolerOutOfProcessTests
 LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/packages/PrintSpooler/tests/outofprocess/AndroidManifest.xml b/packages/PrintSpooler/tests/outofprocess/AndroidManifest.xml
index 4a05f6f..307cc93 100644
--- a/packages/PrintSpooler/tests/outofprocess/AndroidManifest.xml
+++ b/packages/PrintSpooler/tests/outofprocess/AndroidManifest.xml
@@ -21,10 +21,12 @@
     <application>
         <uses-library android:name="android.test.runner" />
 
-        <activity android:name=".PrintTestActivity"/>
+        <activity
+            android:name="android.print.test.PrintDocumentActivity"
+            android:theme="@style/NoAnimation" />
 
         <service
-                android:name=".mockservice.MockPrintService"
+                android:name="android.print.test.services.FirstPrintService"
                 android:permission="android.permission.BIND_PRINT_SERVICE">
 
             <intent-filter>
@@ -37,13 +39,15 @@
         </service>
 
         <activity
-                android:name=".mockservice.SettingsActivity"
+                android:name="android.print.test.services.SettingsActivity"
                 android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
+                android:theme="@style/NoAnimation"
                 android:exported="true">
         </activity>
 
         <activity
-                android:name=".mockservice.AddPrintersActivity"
+                android:name="android.print.test.services.AddPrintersActivity"
+                android:theme="@style/NoAnimation"
                 android:exported="true">
         </activity>
 
diff --git a/packages/PrintSpooler/tests/outofprocess/res/values/themes.xml b/packages/PrintSpooler/tests/outofprocess/res/values/themes.xml
new file mode 100644
index 0000000..49eb257
--- /dev/null
+++ b/packages/PrintSpooler/tests/outofprocess/res/values/themes.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2017 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.
+  -->
+<resources>
+    <style name="NoAnimation" parent="@android:style/Theme.DeviceDefault">
+        <item name="android:windowAnimationStyle">@null</item>
+    </style>
+</resources>
diff --git a/packages/PrintSpooler/tests/outofprocess/res/xml/printservice.xml b/packages/PrintSpooler/tests/outofprocess/res/xml/printservice.xml
index 9eecf45..a6282b1 100644
--- a/packages/PrintSpooler/tests/outofprocess/res/xml/printservice.xml
+++ b/packages/PrintSpooler/tests/outofprocess/res/xml/printservice.xml
@@ -17,4 +17,4 @@
   -->
 
 <print-service  xmlns:android="http://schemas.android.com/apk/res/android"
-        android:addPrintersActivity="com.android.printspooler.outofprocess.tests.mockservice.AddPrintersActivity" />
+        android:addPrintersActivity="android.print.test.services.AddPrintersActivity" />
diff --git a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/BasePrintTest.java b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/BasePrintTest.java
deleted file mode 100644
index 9a7f362..0000000
--- a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/BasePrintTest.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2016 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.printspooler.outofprocess.tests;
-
-import static android.content.pm.PackageManager.GET_META_DATA;
-import static android.content.pm.PackageManager.GET_SERVICES;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doCallRealMethod;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.app.Instrumentation;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.CancellationSignal;
-import android.os.ParcelFileDescriptor;
-import android.print.PrintAttributes;
-import android.print.PrintDocumentAdapter;
-import android.print.PrintManager;
-import android.print.PrinterId;
-import android.printservice.CustomPrinterIconCallback;
-import android.printservice.PrintJob;
-import android.printservice.PrintService;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.rule.ActivityTestRule;
-import android.support.test.uiautomator.UiDevice;
-
-import com.android.printspooler.outofprocess.tests.mockservice.PrintServiceCallbacks;
-import com.android.printspooler.outofprocess.tests.mockservice.PrinterDiscoverySessionCallbacks;
-import com.android.printspooler.outofprocess.tests.mockservice.StubbablePrinterDiscoverySession;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.mockito.stubbing.Answer;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.List;
-
-/**
- * This is the base class for print tests.
- */
-abstract class BasePrintTest {
-    protected static final long OPERATION_TIMEOUT = 30000;
-    private static final String PM_CLEAR_SUCCESS_OUTPUT = "Success";
-    private static final int CURRENT_USER_ID = -2; // Mirrors UserHandle.USER_CURRENT
-    private static String sDisabledPrintServicesBefore;
-
-    private android.print.PrintJob mPrintJob;
-
-    private static Instrumentation sInstrumentation;
-    private static UiDevice sUiDevice;
-
-    @Rule
-    public ActivityTestRule<PrintTestActivity> mActivityRule =
-            new ActivityTestRule<>(PrintTestActivity.class, false, true);
-
-    /**
-     * Return the UI device
-     *
-     * @return the UI device
-     */
-    public UiDevice getUiDevice() {
-        return sUiDevice;
-    }
-
-    protected static Instrumentation getInstrumentation() {
-        return sInstrumentation;
-    }
-
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-        sInstrumentation = InstrumentationRegistry.getInstrumentation();
-        assumeTrue(sInstrumentation.getContext().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_PRINTING));
-
-        sUiDevice = UiDevice.getInstance(sInstrumentation);
-
-        // Make sure we start with a clean slate.
-        clearPrintSpoolerData();
-
-        disablePrintServices(sInstrumentation.getTargetContext().getPackageName());
-
-        // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
-        // Dexmaker is used by mockito.
-        System.setProperty("dexmaker.dexcache", getInstrumentation()
-                .getTargetContext().getCacheDir().getPath());
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws Exception {
-        enablePrintServices();
-    }
-
-    @Before
-    public void unlockScreen() throws Exception {
-        // Unlock screen.
-        runShellCommand("input keyevent KEYCODE_WAKEUP");
-        runShellCommand("wm dismiss-keyguard");
-    }
-
-    @After
-    public void exitActivities() throws Exception {
-        // Exit print spooler
-        getUiDevice().pressBack();
-        getUiDevice().pressBack();
-    }
-
-    protected android.print.PrintJob print(@NonNull final PrintDocumentAdapter adapter,
-            final PrintAttributes attributes) {
-        // Initiate printing as if coming from the app.
-        getInstrumentation().runOnMainSync(() -> {
-            PrintManager printManager = (PrintManager) getActivity()
-                    .getSystemService(Context.PRINT_SERVICE);
-            mPrintJob = printManager.print("Print job", adapter, attributes);
-        });
-
-        return mPrintJob;
-    }
-
-    protected PrintTestActivity getActivity() {
-        return mActivityRule.getActivity();
-    }
-
-    public static String runShellCommand(String cmd)
-            throws IOException {
-        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation().executeShellCommand(cmd);
-        byte[] buf = new byte[512];
-        int bytesRead;
-        FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
-        StringBuilder stdout = new StringBuilder();
-        while ((bytesRead = fis.read(buf)) != -1) {
-            stdout.append(new String(buf, 0, bytesRead));
-        }
-        fis.close();
-        return stdout.toString();
-    }
-
-    protected static void clearPrintSpoolerData() throws Exception {
-        assertTrue("failed to clear print spooler data", runShellCommand(
-                String.format("pm clear --user %d %s", CURRENT_USER_ID,
-                        PrintManager.PRINT_SPOOLER_PACKAGE_NAME)).contains(
-                PM_CLEAR_SUCCESS_OUTPUT));
-    }
-
-    /**
-     * Disable all print services beside the ones we want to leave enabled.
-     *
-     * @param packageToLeaveEnabled The package of the services to leave enabled.
-     */
-    private static void disablePrintServices(String packageToLeaveEnabled) throws IOException {
-        Instrumentation instrumentation = getInstrumentation();
-
-        sDisabledPrintServicesBefore = runShellCommand(
-                "settings get secure " + Settings.Secure.DISABLED_PRINT_SERVICES);
-
-        Intent printServiceIntent = new Intent(android.printservice.PrintService.SERVICE_INTERFACE);
-        List<ResolveInfo> installedServices = instrumentation.getContext().getPackageManager()
-                .queryIntentServices(printServiceIntent, GET_SERVICES | GET_META_DATA);
-
-        StringBuilder builder = new StringBuilder();
-        for (ResolveInfo service : installedServices) {
-            if (packageToLeaveEnabled.equals(service.serviceInfo.packageName)) {
-                continue;
-            }
-            if (builder.length() > 0) {
-                builder.append(":");
-            }
-            builder.append(new ComponentName(service.serviceInfo.packageName,
-                    service.serviceInfo.name).flattenToString());
-        }
-
-        runShellCommand(
-                "settings put secure " + Settings.Secure.DISABLED_PRINT_SERVICES + " " + builder);
-    }
-
-    /**
-     * Revert {@link #disablePrintServices(String)}
-     */
-    private static  void enablePrintServices() throws IOException {
-        runShellCommand("settings put secure " + Settings.Secure.DISABLED_PRINT_SERVICES + " "
-                        + sDisabledPrintServicesBefore);
-    }
-
-    @SuppressWarnings("unchecked")
-    protected PrinterDiscoverySessionCallbacks createMockPrinterDiscoverySessionCallbacks(
-            Answer<Void> onStartPrinterDiscovery, Answer<Void> onStopPrinterDiscovery,
-            Answer<Void> onValidatePrinters, Answer<Void> onStartPrinterStateTracking,
-            Answer<Void> onRequestCustomPrinterIcon, Answer<Void> onStopPrinterStateTracking,
-            Answer<Void> onDestroy) {
-        PrinterDiscoverySessionCallbacks callbacks = mock(PrinterDiscoverySessionCallbacks.class);
-
-        doCallRealMethod().when(callbacks).setSession(any(StubbablePrinterDiscoverySession.class));
-        when(callbacks.getSession()).thenCallRealMethod();
-
-        if (onStartPrinterDiscovery != null) {
-            doAnswer(onStartPrinterDiscovery).when(callbacks).onStartPrinterDiscovery(
-                    any(List.class));
-        }
-        if (onStopPrinterDiscovery != null) {
-            doAnswer(onStopPrinterDiscovery).when(callbacks).onStopPrinterDiscovery();
-        }
-        if (onValidatePrinters != null) {
-            doAnswer(onValidatePrinters).when(callbacks).onValidatePrinters(
-                    any(List.class));
-        }
-        if (onStartPrinterStateTracking != null) {
-            doAnswer(onStartPrinterStateTracking).when(callbacks).onStartPrinterStateTracking(
-                    any(PrinterId.class));
-        }
-        if (onRequestCustomPrinterIcon != null) {
-            doAnswer(onRequestCustomPrinterIcon).when(callbacks).onRequestCustomPrinterIcon(
-                    any(PrinterId.class), any(CancellationSignal.class),
-                    any(CustomPrinterIconCallback.class));
-        }
-        if (onStopPrinterStateTracking != null) {
-            doAnswer(onStopPrinterStateTracking).when(callbacks).onStopPrinterStateTracking(
-                    any(PrinterId.class));
-        }
-        if (onDestroy != null) {
-            doAnswer(onDestroy).when(callbacks).onDestroy();
-        }
-
-        return callbacks;
-    }
-
-    protected PrintServiceCallbacks createMockPrintServiceCallbacks(
-            Answer<PrinterDiscoverySessionCallbacks> onCreatePrinterDiscoverySessionCallbacks,
-            Answer<Void> onPrintJobQueued, Answer<Void> onRequestCancelPrintJob) {
-        final PrintServiceCallbacks service = mock(PrintServiceCallbacks.class);
-
-        doCallRealMethod().when(service).setService(any(PrintService.class));
-        when(service.getService()).thenCallRealMethod();
-
-        if (onCreatePrinterDiscoverySessionCallbacks != null) {
-            doAnswer(onCreatePrinterDiscoverySessionCallbacks).when(service)
-                    .onCreatePrinterDiscoverySessionCallbacks();
-        }
-        if (onPrintJobQueued != null) {
-            doAnswer(onPrintJobQueued).when(service).onPrintJobQueued(any(PrintJob.class));
-        }
-        if (onRequestCancelPrintJob != null) {
-            doAnswer(onRequestCancelPrintJob).when(service).onRequestCancelPrintJob(
-                    any(PrintJob.class));
-        }
-
-        return service;
-    }
-}
diff --git a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/PrintTestActivity.java b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/PrintTestActivity.java
deleted file mode 100644
index 4905a0b..0000000
--- a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/PrintTestActivity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 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.printspooler.outofprocess.tests;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.WindowManager;
-
-public class PrintTestActivity extends Activity {
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
-    }
-}
diff --git a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/WorkflowTest.java b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/WorkflowTest.java
index 78a0cac..7ebf93d 100644
--- a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/WorkflowTest.java
+++ b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/WorkflowTest.java
@@ -30,6 +30,11 @@
 import android.print.PrinterId;
 import android.print.PrinterInfo;
 import android.print.pdf.PrintedPdfDocument;
+import android.print.test.BasePrintTest;
+import android.print.test.services.AddPrintersActivity;
+import android.print.test.services.FirstPrintService;
+import android.print.test.services.PrinterDiscoverySessionCallbacks;
+import android.print.test.services.StubbablePrinterDiscoverySession;
 import android.support.test.filters.LargeTest;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject;
@@ -38,11 +43,6 @@
 import android.support.test.uiautomator.Until;
 import android.util.Log;
 
-import com.android.printspooler.outofprocess.tests.mockservice.AddPrintersActivity;
-import com.android.printspooler.outofprocess.tests.mockservice.MockPrintService;
-import com.android.printspooler.outofprocess.tests.mockservice.PrinterDiscoverySessionCallbacks;
-import com.android.printspooler.outofprocess.tests.mockservice.StubbablePrinterDiscoverySession;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -62,10 +62,6 @@
 public class WorkflowTest extends BasePrintTest {
     private static final String LOG_TAG = WorkflowTest.class.getSimpleName();
 
-    private static float sWindowAnimationScaleBefore;
-    private static float sTransitionAnimationScaleBefore;
-    private static float sAnimatiorDurationScaleBefore;
-
     private PrintAttributes.MediaSize mFirst;
     private boolean mSelectPrinter;
     private PrintAttributes.MediaSize mSecond;
@@ -91,7 +87,7 @@
             throws TimeoutException, InterruptedException {
         long startTime = System.currentTimeMillis();
         while (condition.get()) {
-            long timeLeft = OPERATION_TIMEOUT - (System.currentTimeMillis() - startTime);
+            long timeLeft = OPERATION_TIMEOUT_MILLIS - (System.currentTimeMillis() - startTime);
             if (timeLeft < 0) {
                 throw new TimeoutException();
             }
@@ -156,7 +152,7 @@
      */
     private void setMockPrintServiceCallbacks(StubbablePrinterDiscoverySession[] sessionRef,
             ArrayList<String> trackedPrinters, PrintAttributes.MediaSize mediaSize) {
-        MockPrintService.setCallbacks(createMockPrintServiceCallbacks(
+        FirstPrintService.setCallbacks(createMockPrintServiceCallbacks(
                 inv -> createMockPrinterDiscoverySessionCallbacks(inv2 -> {
                             synchronized (sessionRef) {
                                 sessionRef[0] = ((PrinterDiscoverySessionCallbacks) inv2.getMock())
@@ -243,7 +239,7 @@
                     callback.onWriteFailed(e.getMessage());
                 }
             }
-        }, null);
+        }, (PrintAttributes) null);
     }
 
     @Parameterized.Parameters
@@ -303,7 +299,7 @@
         } else {
             Log.i(LOG_TAG, "Waiting for error message");
             assertNotNull(getUiDevice().wait(Until.findObject(
-                    By.text("This printer isn't available right now.")), OPERATION_TIMEOUT));
+                    By.text("This printer isn't available right now.")), OPERATION_TIMEOUT_MILLIS));
         }
 
         setPrinter("All printers\u2026");
@@ -316,7 +312,7 @@
                 () -> addPrinter(session[0], "2nd printer", mSecond));
 
         // This executes the observer registered above
-        clickOn(new UiSelector().text(MockPrintService.class.getCanonicalName())
+        clickOn(new UiSelector().text(FirstPrintService.class.getCanonicalName())
                 .resourceId("com.android.printspooler:id/title"));
 
         getUiDevice().pressBack();
@@ -342,7 +338,8 @@
             } else {
                 Log.i(LOG_TAG, "Waiting for error message");
                 assertNotNull(getUiDevice().wait(Until.findObject(
-                        By.text("This printer isn't available right now.")), OPERATION_TIMEOUT));
+                        By.text("This printer isn't available right now.")),
+                        OPERATION_TIMEOUT_MILLIS));
             }
 
             Log.i(LOG_TAG, "Waiting for 1st printer to be not tracked");
@@ -370,7 +367,8 @@
             } else {
                 Log.i(LOG_TAG, "Waiting for error message");
                 assertNotNull(getUiDevice().wait(Until.findObject(
-                        By.text("This printer isn't available right now.")), OPERATION_TIMEOUT));
+                        By.text("This printer isn't available right now.")),
+                        OPERATION_TIMEOUT_MILLIS));
             }
 
             Log.i(LOG_TAG, "Waiting for 1st printer to be tracked");
diff --git a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/AddPrintersActivity.java b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/AddPrintersActivity.java
deleted file mode 100644
index 2ea4e7d..0000000
--- a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/AddPrintersActivity.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-
-import java.util.ArrayList;
-
-public class AddPrintersActivity extends Activity {
-    private static final ArrayList<Runnable> sObservers = new ArrayList<>();
-
-    public static void addObserver(@NonNull Runnable observer) {
-        synchronized (sObservers) {
-            sObservers.add(observer);
-        }
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        synchronized (sObservers) {
-            for (Runnable sObserver : sObservers) {
-                sObserver.run();
-            }
-        }
-
-        finish();
-    }
-
-    public static void clearObservers() {
-        synchronized (sObservers) {
-            sObservers.clear();
-        }
-    }
-}
diff --git a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/MockPrintService.java b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/MockPrintService.java
deleted file mode 100644
index 3a23113..0000000
--- a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/MockPrintService.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
-
-public class MockPrintService extends StubbablePrintService {
-
-    private static final Object sLock = new Object();
-
-    private static PrintServiceCallbacks sCallbacks;
-
-    public static void setCallbacks(PrintServiceCallbacks callbacks) {
-        synchronized (sLock) {
-            sCallbacks = callbacks;
-        }
-    }
-
-    @Override
-    protected PrintServiceCallbacks getCallbacks() {
-        synchronized (sLock) {
-            if (sCallbacks != null) {
-                sCallbacks.setService(this);
-            }
-            return sCallbacks;
-        }
-    }
-}
diff --git a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/PrintServiceCallbacks.java b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/PrintServiceCallbacks.java
deleted file mode 100644
index 07baa0f..0000000
--- a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/PrintServiceCallbacks.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
-
-import android.printservice.PrintJob;
-import android.printservice.PrintService;
-
-public abstract class PrintServiceCallbacks {
-
-    private PrintService mService;
-
-    public PrintService getService() {
-        return mService;
-    }
-
-    public void setService(PrintService service) {
-        mService = service;
-    }
-
-    public abstract PrinterDiscoverySessionCallbacks onCreatePrinterDiscoverySessionCallbacks();
-
-    public abstract void onRequestCancelPrintJob(PrintJob printJob);
-
-    public abstract void onPrintJobQueued(PrintJob printJob);
-}
diff --git a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/PrinterDiscoverySessionCallbacks.java b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/PrinterDiscoverySessionCallbacks.java
deleted file mode 100644
index 5c1260c..0000000
--- a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/PrinterDiscoverySessionCallbacks.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
-
-import android.os.CancellationSignal;
-import android.print.PrinterId;
-import android.printservice.CustomPrinterIconCallback;
-
-import java.util.List;
-
-public abstract class PrinterDiscoverySessionCallbacks {
-
-    private StubbablePrinterDiscoverySession mSession;
-
-    public void setSession(StubbablePrinterDiscoverySession session) {
-        mSession = session;
-    }
-
-    public StubbablePrinterDiscoverySession getSession() {
-        return mSession;
-    }
-
-    public abstract void onStartPrinterDiscovery(List<PrinterId> priorityList);
-
-    public abstract void onStopPrinterDiscovery();
-
-    public abstract void onValidatePrinters(List<PrinterId> printerIds);
-
-    public abstract void onStartPrinterStateTracking(PrinterId printerId);
-
-    public abstract void onRequestCustomPrinterIcon(PrinterId printerId,
-            CancellationSignal cancellationSignal, CustomPrinterIconCallback callback);
-
-    public abstract void onStopPrinterStateTracking(PrinterId printerId);
-
-    public abstract void onDestroy();
-}
diff --git a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/StubbablePrintService.java b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/StubbablePrintService.java
deleted file mode 100644
index be9d19b..0000000
--- a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/StubbablePrintService.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
-
-import android.printservice.PrintJob;
-import android.printservice.PrintService;
-import android.printservice.PrinterDiscoverySession;
-
-public abstract class StubbablePrintService extends PrintService {
-
-    @Override
-    public PrinterDiscoverySession onCreatePrinterDiscoverySession() {
-        PrintServiceCallbacks callbacks = getCallbacks();
-        if (callbacks != null) {
-            return new StubbablePrinterDiscoverySession(this,
-                    getCallbacks().onCreatePrinterDiscoverySessionCallbacks());
-        }
-        return null;
-    }
-
-    @Override
-    public void onRequestCancelPrintJob(PrintJob printJob) {
-        PrintServiceCallbacks callbacks = getCallbacks();
-        if (callbacks != null) {
-            callbacks.onRequestCancelPrintJob(printJob);
-        }
-    }
-
-    @Override
-    public void onPrintJobQueued(PrintJob printJob) {
-        PrintServiceCallbacks callbacks = getCallbacks();
-        if (callbacks != null) {
-            callbacks.onPrintJobQueued(printJob);
-        }
-    }
-
-    protected abstract PrintServiceCallbacks getCallbacks();
-}
diff --git a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/StubbablePrinterDiscoverySession.java b/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/StubbablePrinterDiscoverySession.java
deleted file mode 100644
index a828cd6..0000000
--- a/packages/PrintSpooler/tests/outofprocess/src/com/android/printspooler/outofprocess/tests/mockservice/StubbablePrinterDiscoverySession.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
-
-import android.os.CancellationSignal;
-import android.print.PrinterId;
-import android.printservice.CustomPrinterIconCallback;
-import android.printservice.PrintService;
-import android.printservice.PrinterDiscoverySession;
-import android.support.annotation.NonNull;
-
-import java.util.List;
-
-public class StubbablePrinterDiscoverySession extends PrinterDiscoverySession {
-    private final PrintService mService;
-    private final PrinterDiscoverySessionCallbacks mCallbacks;
-
-    public StubbablePrinterDiscoverySession(PrintService service,
-            PrinterDiscoverySessionCallbacks callbacks) {
-        mService = service;
-        mCallbacks = callbacks;
-        if (mCallbacks != null) {
-            mCallbacks.setSession(this);
-        }
-    }
-
-    public PrintService getService() {
-        return mService;
-    }
-
-    @Override
-    public void onStartPrinterDiscovery(@NonNull List<PrinterId> priorityList) {
-        if (mCallbacks != null) {
-            mCallbacks.onStartPrinterDiscovery(priorityList);
-        }
-    }
-
-    @Override
-    public void onStopPrinterDiscovery() {
-        if (mCallbacks != null) {
-            mCallbacks.onStopPrinterDiscovery();
-        }
-    }
-
-    @Override
-    public void onValidatePrinters(@NonNull List<PrinterId> printerIds) {
-        if (mCallbacks != null) {
-            mCallbacks.onValidatePrinters(printerIds);
-        }
-    }
-
-    @Override
-    public void onStartPrinterStateTracking(@NonNull PrinterId printerId) {
-        if (mCallbacks != null) {
-            mCallbacks.onStartPrinterStateTracking(printerId);
-        }
-    }
-
-    @Override
-    public void onRequestCustomPrinterIcon(@NonNull PrinterId printerId,
-            @NonNull CancellationSignal cancellationSignal,
-            @NonNull CustomPrinterIconCallback callback) {
-        if (mCallbacks != null) {
-            mCallbacks.onRequestCustomPrinterIcon(printerId, cancellationSignal, callback);
-        }
-    }
-
-    @Override
-    public void onStopPrinterStateTracking(@NonNull PrinterId printerId) {
-        if (mCallbacks != null) {
-            mCallbacks.onStopPrinterStateTracking(printerId);
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mCallbacks != null) {
-            mCallbacks.onDestroy();
-        }
-    }
-}
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index cf9515e..a7a7ea9 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Kon nie instellings vir <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> oopmaak nie"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Die invoermetode kan dalk alle teks wat jy invoer, versamel, insluitend persoonlike data soos wagwoorde en kredietkaartnommers. Dit kom van die program <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Wil jy dié invoermetode gebruik?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Let wel: Ná \'n herselflaai kan hierdie program nie begin voordat jy jou foon ontsluit het nie"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS-registrasiestaat"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Geregistreer"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Nie geregistreer nie"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Onbeskikbaar"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index a84ee81..bff8fe2 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"የ<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> ቅንብሮች መክፈት አልተሳካም"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ይህ ግቤት ስልት የሚትተይበውን ፅሁፍ ሁሉ፣  እንደይለፍ ቃል እና የብድር ካርድ ጨምሮ የግል ውሂብ ምናልባት መሰብሰብ ይችላል። ከትግበራው ይመጣል። <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ይህን ግቤት ስልትይጠቀም?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ማስታወሻ፦ እንደገና ከማስነሳት በኋላ ይህ መተግበሪያ ስልክዎን እስከሚከፍቱት ድረስ ሊጀምር አይችልም"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"የIMS ምዝገባ ቀን"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"የተመዘገበ"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"አልተመዘገበም"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"አይገኝም"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index b9a16b96..457a6dd 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"تعذّر فتح الإعدادات لـ <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"يمكن أن يكون أسلوب الإدخال هذا قادرًا على جمع كل النصوص التي تكتبها، بما في ذلك البيانات الشخصية مثل كلمات المرور وأرقام بطاقات الائتمان. يتم الحصول على هذا الأسلوب من التطبيق <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. هل تريد استخدام أسلوب الإدخال هذا؟"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ملاحظة: بعد إعادة التشغيل، يتعذر بدء هذا التطبيق إلى أن تلغي قفل هاتفك."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"‏حالة تسجيل IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"مُسجَّل"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"غير مُسجَّل"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"غير متاح"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 0a86706..8b453ab 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> üçün ayarları açmaq alınmadı"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Bu daxiletmə metodu yazdığınız bütün mətni toplaya bilər. Buna kredit kart kimi şəxsi məlumat aid ola bilər. Kökü <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> tətbiqindədir. Bu daxiletmə metodu istifadə olunsun?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Qeyd: Yenidən yüklənmədən sonra, bu cihazın kilidini açmamış tətbiq başlaya bilməz"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS qeydiyyat statusu"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Qeydiyyatlı"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Qeydiyyatsız"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Əlçatmazdır"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 1e84d3d..ba0de57 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Otvaranje podešavanja za aplikaciju <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> nije uspelo"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Ovaj metod unosa možda može da prikuplja sav tekst koji unosite, uključujući lične podatke, kao što su lozinke i brojevi kreditnih kartica. Potiče od aplikacije <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Želite li da koristite ovaj metod unosa?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Napomena: Posle restartovanja ova aplikacija ne može da se pokrene dok ne otključate telefon"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Status IMS registracije"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrovan je"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Nije registrovan"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Nedostupno"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index e47bc43..49a18b6 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Не атрымалася адкрыць параметры <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Гэты метад уводу можа збіраць увесь тэкст, які ўводзіцца, у тым лiку такiя персанальныя дадзеныя, як паролі і нумары крэдытных карт. Ён выкарыстоўваецца прыкладаннем <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Выкарыстоўваць гэты метад уводу?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Заўвага. Пасля перазагрузкі гэта праграма не зможа запусціцца, пакуль вы не разблакіруеце тэлефон"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Стан рэгістрацыі IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Зарэгістраваны"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Не зарэгістраваны"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Адсутнічае"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 77beb4c..8fbef19 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Отварянето на настройките за <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> не бе успешно"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Този метод за въвеждане може да събира целия въведен от вас текст, включително лични данни като пароли и номера на кредитни карти. Той произлиза от приложението <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Искате ли да го използвате?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Забележка: След рестартиране това приложение не може да се стартира, докато не отключите телефона си"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Състояние на регистрацията за незабавни съобщения"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Регистрирано"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Не е регистрирано"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Няма данни"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 424e7b9..ec48835 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> জন্য সেটিংস খুলতে ব্যর্থ হয়েছে"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"এই ইনপুট পদ্ধতিটি হয়তো পাসওয়ার্ড এবং ক্রেডিট কার্ড নম্বর সহ আপনার টাইপ করা সমস্ত টেক্সট সংগ্রহ করতে সক্ষম হতে পারে। এটি <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> অ্যাপ থেকে এসেছে। এই ইনপুট পদ্ধতিটি ব্যবহার করবেন?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"দ্রষ্টব্য: পুনরায় চালু করার পরে, আপনি আপনার ফোন আনলক না করা পর্যন্ত এই অ্যাপটিকে চালু করতে পারবেন না"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS রেজিস্ট্রেশনের স্থিতি"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"রেজিস্টার করা"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"রেজিস্টার করা নয়"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"অনুপলব্ধ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 97cbfbf..a331286 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -110,7 +110,7 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Uklonjene aplikacije"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Uklonjene aplikacije i korisnici"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB dijeljenje veze"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"Povezivanje mobitela USB-om"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Prijenosna pristupna tačka"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Dijeljenje Bluetooth veze"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Dijeljenje veze"</string>
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Nije uspjelo otvaranje postavki za <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Ovaj način unosa može prikupiti sav tekst koji otkucate, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Način omogućava aplikacija <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Da li želite koristiti ovaj način unosa?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Napomena: Nakon ponovnog pokretanja, ova aplikacija se neće moći pokrenuti dok ne otključate telefon"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Stanje IMS registracije"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrirano"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Nije registrirano"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Nije dostupno"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 479cf38..145f61c 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"No s\'ha pogut obrir la configuració de: <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Pot ser que aquest mètode d\'introducció pugui recopilar tot el que escriviu, incloses dades personals, com ara contrasenyes i números de targetes de crèdit. Ve de l\'aplicació <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voleu utilitzar aquest mètode d\'introducció?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Nota: després de reiniciar, l\'aplicació no s\'iniciarà fins que no desbloquegis el telèfon"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Estat del registre d\'IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrat"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Sense registrar"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"No disponible"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 97a76f7..994afae 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Nastavení aplikace <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> se nepodařilo otevřít"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Prostřednictvím této vstupní metody zadávání dat lze shromažďovat zadaný text včetně osobních údajů, jako jsou hesla a čísla platebních karet. Metoda je poskytována aplikací <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Chcete tuto metodu zadávání dat použít?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Poznámka: Po restartování se tato aplikace nespustí, dokud telefon neodemknete."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Stav registrace IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrováno"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Neregistrováno"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Není k dispozici"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 6a006cc..e916853 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -329,7 +329,7 @@
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konvertér…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Allerede filkrypteret"</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"Konverterer til filbaseret kryptering"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Konvertér datapartitionen til filbaseret kryptering.\nAdvarsel! Alle dine data vil blive slettet.\n Dette er en alfafunktion, og den fungerer muligvis ikke korrekt.\n Tryk på \"Ryd og konvertér…\" for at fortsætte."</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Konvertér datapartitionen til filbaseret kryptering.\nAdvarsel! Alle dine data vil blive fuldstændigt slettet.\n Dette er en alfafunktion, og den fungerer muligvis ikke korrekt.\n Tryk på \"Ryd og konvertér…\" for at fortsætte."</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"Ryd og konvertér…"</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"Farvetilstand for billeder"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"Brug sRGB"</string>
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Indstillingerne for <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> kunne ikke åbnes"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Denne inputmetode kan muligvis indsamle al indtastet tekst, f.eks. personlige data såsom adgangskoder og kreditkortnumre. Den kommer fra appen <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Vil du anvende denne inputmetode?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Bemærk! Efter en genstart kan denne app ikke starte, før du låser din telefon op"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Status for IMS-registrering"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registreret"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Ikke registreret"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Utilgængelig"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 2203bc6..1ec4fee 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Einstellungen für <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> konnten nicht geöffnet werden."</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Diese Eingabemethode kann den gesamten von dir eingegebenen Text erfassen, einschließlich personenbezogener Daten wie Passwörter und Kreditkartennummern. Sie ist Teil der App \"<xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>\". Möchtest du diese Eingabemethode verwenden?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Hinweis: Nach einem Neustart wird diese App erst gestartet, wenn du dein Smartphone entsperrst"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS-Registrierungsstatus"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registriert"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Nicht registriert"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Nicht verfügbar"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 514cfd8..2548a5d 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Δεν ήταν δυνατό το άνοιγμα των ρυθμίσεων για την εφαρμογή <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Αυτή η μέθοδος εισαγωγής ενδέχεται να έχει τη δυνατότητα να συλλέξει όλα τα κείμενα που πληκτρολογείτε, συμπεριλαμβανομένων προσωπικών δεδομένων, όπως είναι οι κωδικοί πρόσβασης και οι αριθμοί πιστωτικής κάρτας. Προέρχεται από την εφαρμογή <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Να γίνει χρήση αυτής της μεθόδου εισαγωγής;"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Σημείωση: Μετά από μια επανεκκίνηση, δεν είναι δυνατή η έναρξη αυτής της συσκευής προτού ξεκλειδώσετε το τηλέφωνό σας"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Κατάσταση εγγραφής υπηρεσίας IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Εγγεγραμμένη"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Μη εγγεγραμμένη"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Μη διαθέσιμο"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index aa5af8e..9e24004 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Failed to open settings for <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"This input method may be able to collect all the text that you type, including personal data like passwords and credit card numbers. It comes from the app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Use this input method?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Note: After a reboot, this app can\'t start until you unlock your phone"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS registration state"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registered"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Not registered"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Unavailable"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index aa5af8e..9e24004 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Failed to open settings for <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"This input method may be able to collect all the text that you type, including personal data like passwords and credit card numbers. It comes from the app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Use this input method?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Note: After a reboot, this app can\'t start until you unlock your phone"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS registration state"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registered"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Not registered"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Unavailable"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index aa5af8e..9e24004 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Failed to open settings for <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"This input method may be able to collect all the text that you type, including personal data like passwords and credit card numbers. It comes from the app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Use this input method?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Note: After a reboot, this app can\'t start until you unlock your phone"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS registration state"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registered"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Not registered"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Unavailable"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index aa5af8e..9e24004 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Failed to open settings for <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"This input method may be able to collect all the text that you type, including personal data like passwords and credit card numbers. It comes from the app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Use this input method?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Note: After a reboot, this app can\'t start until you unlock your phone"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS registration state"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registered"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Not registered"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Unavailable"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 66d8fe0..77c0e4f 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‎Failed to open settings for ‎‏‎‎‏‏‎<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎This input method may be able to collect all the text you type, including personal data like passwords and credit card numbers. It comes from the app ‎‏‎‎‏‏‎<xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. Use this input method?‎‏‎‎‏‎"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎Note: After a reboot, this app can\'t start until you unlock your phone‎‏‎‎‏‎"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‎‎‎‏‏‎IMS registration state‎‏‎‎‏‎"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‎‎‎Registered‎‏‎‎‏‎"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎Not registered‎‏‎‎‏‎"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‎‎‎‏‎‎Unavailable‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 743700e..ff26eef 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Se produjo un error al abrir la configuración de <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>."</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"El método de entrada puede recopilar todo el texto que escribas, incluidos los datos personales como contraseñas y números de tarjetas de crédito. Proviene de la aplicación <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. ¿Deseas utilizar este método de entrada?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Nota: Luego de reiniciar el dispositivo, esta app no podrá iniciarse hasta que desbloquees tu teléfono"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Estado de registro de IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrado"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Sin registrar"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"No disponible"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index d964728..20bab13 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Error al abrir los ajustes de <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Este método de entrada puede registrar todo lo que escribas, incluidos datos personales, como las contraseñas y los números de las tarjetas de crédito. Procede de la aplicación <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. ¿Quieres usar este método de entrada?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Nota: Después de reiniciar, tienes que desbloquear el teléfono para que esta aplicación se pueda iniciar"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Estado del registro de IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrado"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"No registrado"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"No disponible"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index cfcc4c6..a0341fb 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Rakenduse <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> seadete avamine ebaõnnestus"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"See sisestusmeetod võib koguda kogu teie sisestatava teksti, sh isikuandmed (nt paroolid ja krediitkaardinumbrid). See pärineb rakendusest <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Kas soovite seda sisestusmeetodit kasutada?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Märkus. Pärast taaskäivitamist ei saa see rakendus käivituda enne, kui olete telefoni avanud"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS-i registreerimise olek"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registreeritud"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Ei ole registreeritud"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Pole saadaval"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index d7595e8..e8d9a5e 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Ezin izan dira <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> aplikazioaren ezarpenak ireki."</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Idazketa-metodoak idazten duzun testu guztia bil dezake, pasahitzak eta kreditu-txarteleko zenbakiak bezalako datu pertsonalak barne. <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> aplikazioak egin du eskaera. Idazketa-metodo hori erabili nahi duzu?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Oharra: berrabiarazi ondoren, ezin izango da abiarazi aplikazio hau telefonoa desblokeatzen duzun arte"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS erregistratzearen egoera"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Erregistratuta"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Erregistratu gabe"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Ez dago erabilgarri"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index f582486..326192d 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"تنظیمات <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> بازنشد"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"این روش ورودی ممکن است بتواند تمام متنی را که تایپ می‌کنید جمع‌آوری کند، از جمله اطلاعات شخصی مانند گذرواژه‌ها و شماره‌های کارت اعتباری. این روش توسط برنامه <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ارائه می‌شود. از این روش ورودی استفاده می‌کنید؟"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"توجه: بعد از راه‌اندازی تا زمانی‌که قفل تلفنتان را باز نکنید، این برنامه نمی‌تواند شروع شود"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"‏وضعیت ثبت IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"ثبت‌شده"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"ثبت نشده است"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"در دسترس نیست"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 83073d1..6321086 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Sovelluksen <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> asetuksia ei voi avata"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Tämä syöttötapa saattaa kerätä kaiken kirjoittamasi tekstin, mukaan luettuna henkilökohtaiset tiedot kuten salasanat ja luottokortin numerot. Se on lähtöisin sovelluksesta <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Käytetäänkö tätä syöttötapaa?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Huom. Jotta voit käynnistää tämän sovelluksen uudelleenkäynnistyksen jälkeen, sinun täytyy avata puhelimen lukitus."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS-rekisteröinnin tila"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Rekisteröity"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Ei rekisteröity"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Ei käytettävissä"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 54d6864..00c02ce 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Échec de l\'ouverture des paramètres de l\'application <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>."</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Ce mode de saisie est susceptible d\'enregistrer le texte que vous saisissez, y compris vos données personnelles, telles que les mots de passe et les numéros de carte de paiement. Il provient de l\'application <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voulez-vous vraiment l\'activer?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Remarque : Après un redémarrage, vous ne pouvez pas lancer cette application tant que vous n\'avez pas déverrouillé votre téléphone."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"État d\'enregistrement IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Enregistré"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Non enregistré"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Non accessible"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index e35d330..a5625e4 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Échec de l\'ouverture des paramètres de l\'application <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>."</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Ce mode de saisie est susceptible d\'enregistrer le texte que vous saisissez, y compris vos données personnelles, telles que les mots de passe et les numéros de carte de paiement. Il provient de l\'application <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voulez-vous vraiment l\'activer ?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Remarque : Après un redémarrage, vous ne pouvez pas lancer cette application tant que vous n\'avez pas déverrouillé votre téléphone."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"État de l\'enregistrement IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Enregistré"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Non enregistré"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Non disponible"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 8291cb1..e1ea694 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Non se puido abrir a configuración de <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"É posible que este método de entrada poida recompilar todo o texto que escribas, incluídos os datos persoais como os contrasinais e os números de tarxetas de crédito. Provén da aplicación <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Queres usar este método de entrada?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Nota: Tras un reinicio, non se pode iniciar esta aplicación ata que desbloquees o teléfono"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Estado de rexistro de IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Rexistrado"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Non rexistrado"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Non dispoñible"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index ca14118..0e8dd47 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> માટેની સેટિંગ્સ ખોલવામાં નિષ્ફળ"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"આ ઇનપુટ પદ્ધતિ પાસવર્ડ્સ અને ક્રેડિટ કાર્ડ નંબર જેવી વ્યક્તિગત માહિતી સહિત તમે લખો છો તે તમામ ટેક્સ્ટ એકત્રિત કરવા માટે સક્ષમ હોઈ શકે છે. તે ઍપ્લિકેશન <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> માંથી આવે છે. આ ઇનપુટ પદ્ધતિ વાપરીએ?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"નોંધ: રીબૂટ કર્યાં પછી, જ્યાં સુધી તમે તમારો ફોન અનલૉક કરશો નહીં ત્યાં સુધી આ ઍપ્લિકેશન શરૂ થઈ શકશે નહીં"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS રજિસ્ટ્રેશનની સ્થિતિ"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"રજિસ્ટર કરેલ"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"રજિસ્ટર કરેલ નથી"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"અનુપલબ્ધ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index bde80f2..28bc68a 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> के लिए सेटिंग खोलने में विफल रहा"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"यह इनपुट विधि, पासवर्ड और क्रेडिट कार्ड नंबर जैसे निजी डेटा सहित आपके द्वारा लिखे जाने वाले सभी लेख को एकत्र कर सकती है. यह <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ऐप्स से आती है. इस इनपुट विधि का उपयोग करें?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"नोट: पुनः बूट करने के बाद, यह ऐप्लिकेशन तब तक शुरू नहीं हो सकता है जब तक कि आप अपना फ़ोन अनलॉक ना कर लें"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS रजिस्ट्रेशन की स्थिति"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"रजिस्टर है"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"रजिस्टर नहीं है"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"अनुपलब्ध"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index ec2b9cf..b5c5439 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Otvaranje postavki za aplikaciju <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> nije uspjelo"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Ovaj način unosa možda može prikupljati sav tekst koji unosite, uključujući osobne podatke poput zaporki i brojeva kreditnih kartica. To omogućuje aplikacija <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Upotrijebiti taj način unosa?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Napomena: ova se aplikacija ne može pokrenuti nakon ponovnog pokretanja dok ne otključate telefon"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Stanje registracije IMS-a"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrirano"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Nije registrirano"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Nije dostupno"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 3fe6a78..47d6c98 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Nem sikerült megnyitni a(z) <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> beállításait."</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Ez a beviteli módszer alkalmas lehet a beírt szövegek – köztük az olyan személyes adatok, mint a jelszavak és a hitelkártyaszámok - összegyűjtésére. A <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> alkalmazás kapcsolta be. Használja ezt a módszert?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Megjegyzés: Újraindítás után ez az alkalmazás csak a telefon feloldását követően indul el"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS-regisztráció állapota"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Regisztrált"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Nem regisztrált"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Nem érhető el"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 119e24c..6f11cd8 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Չստացվեց ցույց տալ <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>-ի տվյալները"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Այս ներմուծման եղանակը հնարավորություն է տալիս հավաքել ձեր մուտքագրած ողջ տեքստը՝ ընդգրկելով անձնական տեղեկություններ, ինչպես գաղտնաբառն ու բանկային քարտի համարները: Սկզբնաղբյուրը <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> հավելվածն է: Կիրառե՞լ այս եղանակը:"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Ուշադրություն. Վերաբեռնումից հետո այս հավելվածը չի գործարկվի մինչև չապակողպեք հեռախոսը"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS ծառայության գրանցման կարգավիճակը"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Գրանցված է"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Գրանցված չէ"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Անհասանելի"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index c2db508..b4a58bb 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Gagal membuka setelan untuk <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Metode masukan ini mungkin dapat mengumpulkan semua teks yang Anda ketik, termasuk data pribadi seperti sandi dan nomor kartu kredit. Metode ini berasal dari aplikasi <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Gunakan metode masukan ini?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Catatan: Setelah boot ulang, aplikasi ini tidak dapat dimulai hingga kunci ponsel dibuka"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Status pendaftaran IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Terdaftar"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Tidak terdaftar"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Tidak Tersedia"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 883e909..29b1b5d 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Ekki tókst að opna stillingar <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Þessi innsláttaraðferð getur hugsanlega skráð allan texta sem þú slærð inn, þ. á m. persónuupplýsingar á borð við aðgangsorð og kreditkortanúmer. Hún kemur frá forritinu <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Viltu nota þessa innsláttaraðferð?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Athugaðu: Eftir endurræsingu er ekki hægt að ræsa þetta forrit fyrr en þú tekur símann úr lás"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Staða IMS-skráningar"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Skráð"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Ekki skráð"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Ekki tiltækt"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index e53e4da..46004c3 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Impossibile aprire le impostazioni di <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Questo metodo di immissione potrebbe riuscire a raccogliere tutto il testo digitato, compresi i dati personali come password e numeri di carte di credito. Deriva dall\'applicazione <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Utilizzare questo metodo di immissione?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Nota: dopo il riavvio, devi sbloccare il telefono per poter avviare l\'app."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Stato di registrazione IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrato"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Non registrato"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Non disponibile"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 363b064..24f4684 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"פתיחת הגדרות עבור <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> נכשלה"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ייתכן ששיטת קלט זו תוכל לאסוף את כל הטקסט שאתה מקליד, כולל נתונים אישיים כגון סיסמאות ומספרי כרטיס אשראי. היא מגיעה מהאפליקציה <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. האם להשתמש בשיטת קלט זו?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"שים לב: לאחר הפעלה מחדש של המכשיר, ניתן להפעיל את האפליקציה רק לאחר שתבטל את נעילת הטלפון"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"‏סטטוס הרשמה ל-IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"רשום"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"לא רשום"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"לא זמין"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index dfd199a..bb3f5a9 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -390,4 +390,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>の設定を開くことができませんでした"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"この入力方法を選択すると、すべての入力内容の収集をアプリ(<xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>)に許可することになります。これにはパスワードやクレジットカード番号などの個人情報も含まれます。この入力方法を使用しますか?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"注: 再起動後、スマートフォンのロックを解除するまでこのアプリを起動することはできません"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS 登録ステータス"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"登録済み"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"未登録"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"不明"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 7fac639..2280261 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>-ისთვის პარამეტრების გახსნა ვერ მოხერხდა"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"შეყვანის ამ მეთოდმა შესაძლოა მოახერხოს თქვენი აკრეფილი ყველა ტექსტის, მათ შორის პერსონალური მონაცემების, პაროლებისა და საკრედიტო ბარათის ნომრების შენახვა. ეს მეთოდი ეკუთვნის <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>-ს. გამოვიყენო შეყვანის ეს მეთოდი?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"შენიშვნა: გადატვირთვის შემდეგ, ეს აპი ვერ გაეშვება, სანამ ტელეფონს არ განბლოკავთ"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS რეგისტრაციის სტატუსი"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"რეგისტრირებული"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"არარეგისტრირებული"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"მიუწვდომელია"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 3b806a5..03bd3cd 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> қолданбасы үшін параметрлерді ашу орындалмады"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Бұл енгізу әдісі сіз терген барлық мәтінді, кілтсөз және кредит карта нөмірлері сияқты жеке ақпаратты қоса, жинауы мүмкін. Бұл <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> қолданбасы арқылы жасалады. Осы әдіс қолданылсын ба?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Ескертпе: қайта жүктегеннен кейін, телефонның құлпын ашпайынша, бұл қолданба іске қосылмайды"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS тіркеу күйі"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Тіркелген"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Тіркелмеген"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Қол жетімсіз"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 2160bae..6414141 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"បាន​បរាជ័យ​ក្នុង​ការ​បើក​ការ​កំណត់​សម្រាប់ <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"វិធី​សាស្ត្រ​បញ្ចូល​នេះ​អាច​​ប្រមូល​អត្ថបទ​ដែល​អ្នក​វាយ​ទាំងអស់ រួម​មាន​ទិន្នន័យ​ផ្ទាល់ខ្លួន ដូច​ជ ពាក្យ​សម្ងាត់ និង​លេខ​កាត​ឥណទាន។ វា​បាន​មក​ពី​កម្មវិធី <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ។ ប្រើ​វិធី​សាស្ត្រ​បញ្ចូល​នេះ?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ចំណាំ៖ បន្ទាប់ពីបិទបើកឡើងវិញហើយ កម្មវិធីនេះមិនអាចចាប់ផ្តើមបានទេ រហូតទាល់តែអ្នកដោះសោទូរស័ព្ទរបស់អ្នក"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"ស្ថានភាព​នៃការ​ចុះឈ្មោះ IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"បាន​ចុះឈ្មោះ"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"មិនបាន​ចុះឈ្មោះ"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"មិន​មាន"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index a47a92c..d108dd6 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -121,7 +121,7 @@
     <string name="running_process_item_user_label" msgid="3129887865552025943">"ಬಳಕೆದಾರ: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"ಕೆಲವು ಡೀಫಾಲ್ಟ್‌ಗಳನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"ಡೀಫಾಲ್ಟ್‌ಗಳನ್ನು ಹೊಂದಿಸಲಾಗಿಲ್ಲ"</string>
-    <string name="tts_settings" msgid="8186971894801348327">"ಪಠ್ಯದಿಂದ ಧ್ವನಿಗೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+    <string name="tts_settings" msgid="8186971894801348327">"ಪಠ್ಯದಿಂದ ಧ್ವನಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"ಧ್ವನಿಗೆ-ಪಠ್ಯದ ಔಟ್‌ಪುಟ್‌"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"ಧ್ವನಿಯ ಪ್ರಮಾಣ"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"ಪಠ್ಯವನ್ನು ಹೇಳಿದ ವೇಗ"</string>
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> ಗಾಗಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಲು ವಿಫಲವಾಗಿದೆ"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ವೈಯಕ್ತಿಕ ಡೇಟಾಗಳಾದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಸಂಖ್ಯೆಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ನೀವು ಟೈಪ್ ಮಾಡುವ ಎಲ್ಲ ಪಠ್ಯವನ್ನು ಸಂಗ್ರಹಿಸಲು ಈ ಇನ್‌ಪುಟ್ ವಿಧಾನಕ್ಕೆ ಸಾಧ್ಯವಾಗಬಹುದು. ಇದು <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಬರುತ್ತದೆ. ಈ ಇನ್‌ಪುಟ್ ವಿಧಾನವನ್ನು ಬಳಸುವುದೇ?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ಗಮನಿಸಿ: ರೀಬೂಟ್ ನಂತರ, ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ನೀವು ಅನ್‌ಲಾಕ್ ಮಾಡುವ ತನಕ ಈ ಆಪ್ ಪ್ರಾರಂಭಗೊಳ್ಳುವುದಿಲ್ಲ"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS ನೋಂದಣಿ ಸ್ಥಿತಿ"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"ನೋಂದಾಯಿಸಲಾಗಿದೆ"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"ನೋಂದಾಯಿಸಲಾಗಿಲ್ಲ"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"ಲಭ್ಯವಿಲ್ಲ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 852c78e..ec03fb1 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> 설정을 열지 못했음"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"<xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> 앱에서 지원하는 이 입력 방법을 사용하면 비밀번호 및 신용카드 번호와 같은 개인 정보를 비롯하여 입력한 모든 텍스트가 수집될 수 있습니다. 사용하시겠습니까?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"참고: 재부팅한 후 이 앱은 휴대전화를 잠금 해제해야 시작됩니다."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS 등록 상태"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"등록됨"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"등록되지 않음"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"사용할 수 없음"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 380d0ff..883811d 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> тууралоолору ачылган жок"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Бул киргизүү ыкмасы сиз терген бардык тексттер, сырсөздөр жана кредиттик  карталар сыяктуу жеке маалыматтарды кошо чогултушу мүмкүн. Бул <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> колдонмосу менен байланыштуу. Ушул киргизүү ыкма колдонулсунбу?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Эскертүү: Өчүрүп-күйгүзгөндөн кийин, бул колдонмо телефондун кулпусу ачылмайынча иштебейт"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS каттоо абалы"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Катталган"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Катталган эмес"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Жеткиликсиз"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index eb10dbb..464b490 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"ລົ້ມເຫລວໃນການເປີດການຕັ້ງຄ່າຂອງ <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ວິທີການປ້ອນຂໍ້ມູນນີ້ ອາດສາມາດເກັບກຳທຸກຂໍ້ຄວາມທີ່ທ່ານພິມ, ຮວມເຖິງຂໍ້ມູນສ່ວນໂຕເຊັ່ນລະຫັດຜ່ານ ແລະໝາຍເລກບັດເຄຣດິດນຳ. ມັນມາຈາກແອັບຯ <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. ທ່ານຕ້ອງການໃຊ້ວິທີການປ້ອນຂໍ້ມູນນີ້ບໍ່?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ໝາຍເຫດ: ຫຼັງຈາກເປີດຂຶ້ນມາໃໝ່ແລ້ວ, ແອັບນີ້ຈະບໍ່ສາມາດເລີ່ມໄດ້ຈົນກວ່າທ່ານຈະປົດລັອກໂທລະສັບຂອງທ່ານ"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"ສະຖານະການລົງທະບຽນ IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"ລົງທະບຽນແລ້ວ"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"ບໍ່ໄດ້ລົງທະບຽນ"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"ບໍ່ມີຂໍ້ມູນ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index adf6f8a..fd3bc18 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Nepavyko atidaryti „<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>“ nustatymų"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Naudojant šį įvesties metodą galima rinkti visą įvedamą tekstą, įskaitant asmeninius duomenis, pvz., slaptažodžius ir kredito kortelių numerius. Jis pateikiamas naudojant programą „<xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>“. Naudoti šį įvesties metodą?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Pastaba: paleidus iš naujo nebus galima paleisti programos, kol neatrakinsite telefono"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS registracijos būsena"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Užregistruota"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Neužregistruota"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Užimta"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 280900a..a6d308a 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Neizdevās atvērt lietotnes <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> iestatījumus."</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Izmantojot šo ievades metodi, var tikt vākta informācija par visu ierakstīto tekstu, tostarp personiskiem datiem, piemēram, parolēm un kredītkaršu numuriem. Šī metode ir saistīta ar lietotni <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Vai lietot šo ievades metodi?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Piezīme. Šo lietotni pēc atkārtotas palaišanas nevarēs startēt, kamēr netiks atbloķēts tālrunis."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS reģistrācijas statuss"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Reģistrēts"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Nav reģistrēts"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Nepieejams"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 51697bd..8882cb7 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Подесувањата за <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> не се отворија"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Овој метод на внес може да го собере сиот текст кој го пишувате, вклучувајќи и лични податоци како што се, лозинки и броеви на кредитни картички. Тоа го прави апликацијата <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Користи го овој метод на внес?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Забелешка: по рестартирање, апликацијава не може да се вклучи додека не го отклучите телефонот"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Состојба на IMS-регистрација"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Регистриран"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Не е регистриран"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Недостапен"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index d96607e..8f711b3 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> എന്നതിനായുള്ള ക്രമീകരണങ്ങൾ തുറക്കുന്നതിൽ പരാജയപ്പെട്ടു"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"പാസ്‌വേഡുകൾ, ക്രെഡിറ്റ് കാർഡ് നമ്പറുകൾ എന്നിവ പോലുള്ള വ്യക്തിഗതമായ ഡാറ്റയുൾപ്പെടെ നിങ്ങൾ ടൈപ്പുചെയ്യുന്ന എല്ലാ വാചകവും ഈ ടൈപ്പുചെയ്യൽ രീതിയ്‌ക്ക് ശേഖരിക്കാനായേക്കും. ഇത് <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> അപ്ലിക്കേഷനിൽ നിന്നും വരുന്നു. ഈ ടൈപ്പുചെയ്യൽ രീതി ഉപയോഗിക്കണോ?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ശ്രദ്ധിക്കുക: റീബൂട്ടിന് ശേഷം, ഫോൺ അൺലോക്കുചെയ്യുന്നത് വരെ ഈ ആപ്പ് ആരംഭിക്കാൻ കഴിയില്ല"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS രജിസ്‌ട്രേഷൻ നില"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"രജിസ്റ്റർ ചെയ്‌തു"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"രജിസ്‌റ്റർ ചെയ്‌തിട്ടില്ല"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"ലഭ്യമല്ല"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index e13886d..2e1f5e6 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>-н тохиргоог нээж чадсангүй"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Энэ оруулах арга нь таны нууц үгс, зээлийн картын дугаар гэх мэт бичсэн хувийн мэдээллийг цуглуулах боломжтой байж болно. Үүнийг <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> апп нийлүүлдэг. Энэ оруулах аргыг ашиглах уу?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Санамж: Дахин асаасны дараа энэ апп нь таныг утасны түгжээгээ тайлах хүртэл эхлэх боломжгүй"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS бүртгэлийн байдал"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Бүртгэсэн"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Бүртгээгүй"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Байхгүй"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index ae61916..63e2e87 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> साठी सेटिंग्ज उघडण्यात अयशस्वी"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ही इनपुट पद्धत संकेतशब्द आणि क्रेडिट कार्ड नंबर यासह, आपण टाइप करता तो सर्व मजकूर संकलित करण्यात सक्षम होऊ शकते. ही <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> अॅपवरून येते. ही इनपुट पद्धत वापरायची?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"टीप: रीबूट केल्यानंतर, तुम्ही आपला फोन अनलॉक करे पर्यंत हे अॅप सुरू होऊ शकत नाही"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS नोंदणी स्थिती"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"नोंदवलेले"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"नोंदवलेले नाही"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"अनुपलब्ध"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index a44e5b1..9d81cea 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Gagal membuka tetapan untuk <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Kaedah input ini mungkin boleh mengumpulkan semua teks yang anda taipkan, termasuk data peribadi seperti kata laluan dan nombor kad kredit. Ia datang daripada aplikasi <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Gunakan kaedah input ini?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Perhatian: Selepas but semula, apl ini tidak dapat dimulakan sehingga anda membuka kunci telefon"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Keadaan pendaftaran IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Berdaftar"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Tidak didaftarkan"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Tidak tersedia"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index af95eac..aa241a9 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>အတွက် ဆက်တင်းများဖွင့်ရန် မအောင်မြင်ပါ။"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ဤထည့်သွင်းမှုနည်းလမ်းမှာ သင့်ကိုယ်ရေးအချက်အလက်များဖြစ်သော စကားဝှက်များနှင့် ကရက်ဒစ်ကဒ်နံပါတ်စသည်တို့ကို ရယူသွားမည်ဖြစ်သည်။ <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>အပလီကေးရှင်းမှလာပါသည်။ ဤထည့်သွင်းမှုနည်းလမ်းကို အသုံးပြုမည်လား?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"မှတ်ချက် − ပြန်လည်စတင်ပြီးနောက် သင့်ဖုန်းကိုလော့ခ်မဖွင့်မချင်း ဤအက်ပ်ကို အသုံးပြု၍မရပါ"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS မှတ်ပုံတင်ခြင်း အခြေအနေ"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"မှတ်ပုံတင်ထားသည်"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"မှတ်ပုံတင်မထားပါ"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"မရရှိနိုင်ပါ။"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 13d27ac..daf0051 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Kunne ikke åpne innstillingene for <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Denne inndatametoden har tilgang til all tekst du skriver, blant annet personlige opplysninger som for eksempel passord og kredittkortnumre. Den kommer fra appen <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Vil du bruke denne inndatametoden?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Merk: Etter en omstart kan ikke denne appen starte før du låser opp telefonen din"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Tilstand for IMS-registrering"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrert"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Ikke registrert"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Ikke tilgjengelig"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 58c5ffc..105c442 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>का लागि सेटिङहरू खोल्न विफल भयो।"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"यस इनपुट विधिले तपाईँले टाइप गर्नुहुने सम्पूर्ण पाठ बटु्ल्न सक्छ, व्यक्तिगत डेटा जस्तै पासवर्ड र क्रेडिट कार्ड नम्बर लगायतका। यो <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> अनुप्रयोगबाट आउँदछ। यो इनपुट विधि प्रयोग गर्ने हो?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"टिपोट: पुनःबुट पछि तपाईँले आफ्नो फोनलाई अनलक नगरेसम्म यो अनुप्रयोग सुरु हुन सक्दैन"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS दर्ताको स्थिति"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"दर्ता गरिएको"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"दर्ता नगरिएको"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"अनुपलब्ध"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 5cce79e..d8ae320 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Instellingen openen voor <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> mislukt"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Deze invoermethode verzamelt mogelijk alle tekst die je typt, inclusief persoonlijke gegevens zoals wachtwoorden en creditcardnummers. De methode is afkomstig uit de app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Deze invoermethode inschakelen?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Opmerking: Wanneer je telefoon opnieuw is opgestart, kan deze app pas worden gestart nadat je je telefoon hebt ontgrendeld"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS-registratiestatus"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Geregistreerd"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Niet geregistreerd"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Niet beschikbaar"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index becb559..b54d296 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> ਲਈ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਵਿੱਚ ਅਸਫਲ"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ਇਹ ਇਨਪੁੱਟ ਵਿਧੀ ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤਾ ਜਾਣ ਵਾਲੀ ਸਾਰੀ ਲਿਖਤ ਇਕੱਤਰ ਕਰਨ ਵਿੱਚ ਸਮਰੱਥ ਹੋ ਸਕਦੀ ਹੈ, ਨਿੱਜੀ ਡਾਟਾ ਸਮੇਤ ਜਿਵੇਂ ਪਾਸਵਰਡ ਅਤੇ ਕ੍ਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ। ਇਹ <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ਐਪ ਤੋਂ ਆਉਂਦਾ ਹੈ। ਕੀ ਇਹ ਸਪੈੱਲ ਚੈਕਰ ਵਰਤਣਾ ਹੈ?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ਨੋਟ ਕਰੋ: ਰੀਬੂਟ ਤੋਂ ਬਾਅਦ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਨਹੀਂ ਕਰਦੇ ਤਦ ਤੱਕ ਇਹ ਐਪ ਚਾਲੂ ਨਹੀਂ ਹੋ ਸਕਦੀ"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS ਰਜਿਸਟਰੇਸ਼ਨ ਸਥਿਤੀ"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"ਰਜਿਸਟਰ ਕੀਤੀ ਗਈ"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"ਰਜਿਸਟਰ ਨਹੀਂ ਕੀਤੀ ਗਈ"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"ਅਣਉਪਲਬਧ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index e3c69fb..4810279 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Nie udało się otworzyć ustawień aplikacji <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Ta metoda wprowadzania tekstu może gromadzić cały wpisywany tekst, w tym dane osobowe takie jak hasła czy numery kart kredytowych. Pochodzi ona z aplikacji <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Użyć jej?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Uwaga: po restarcie ta aplikacja będzie mogła uruchomić się dopiero po odblokowaniu telefonu"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Stan rejestracji IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Zarejestrowane"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Niezarejestrowane"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Niedostępny"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 88c69eb..7a080a2 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Falha ao abrir as configurações de <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Este método de entrada pode coletar todo o texto que você digita, incluindo dados pessoais, como senhas e números de cartão de crédito. É um método do app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Usar este método de entrada?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Observação: após uma reinicialização, não é possível iniciar este app até que você desbloqueie seu smartphone"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Estado do registro de IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrado"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Não registrado"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Não disponível"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index dd73f3c..9229e13 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Falha ao abrir as definições para <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Este método de introdução pode permitir a recolha de todo o texto que digitar, incluindo dados pessoais como, por exemplo, palavras-passe e números de cartões de crédito. Decorre da aplicação <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Utilizar este método de introdução?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Nota: após reiniciar, só é possível iniciar esta aplicação quando o telemóvel for desbloqueado."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Estado do registo IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registado"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Não registado"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Indisponível"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 88c69eb..7a080a2 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Falha ao abrir as configurações de <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Este método de entrada pode coletar todo o texto que você digita, incluindo dados pessoais, como senhas e números de cartão de crédito. É um método do app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Usar este método de entrada?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Observação: após uma reinicialização, não é possível iniciar este app até que você desbloqueie seu smartphone"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Estado do registro de IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrado"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Não registrado"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Não disponível"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 93ad315..df34d58 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Deschiderea setărilor pentru <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> a eșuat"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Această metodă de introducere de text poate culege în întregime textul introdus, inclusiv datele personale, cum ar fi parolele și numerele cardurilor de credit. Metoda provine de la aplicația <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Utilizați această metodă de introducere de text?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Notă: după repornire, această aplicație nu poate porni până nu deblocați telefonul"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Situația înregistrării IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Înregistrat"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Neînregistrat"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Indisponibilă"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index ee5169b..3752cb3 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Не удалось открыть настройки приложения \"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>\""</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"При использовании этого способа могут собираться все вводимые данные, в том числе пароли и номера кредитных карт. Запрос поступил от приложения \"<xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>\". Использовать этот способ ввода?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Примечание. Чтобы запустить это приложение после перезагрузки, разблокируйте экран."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Статус регистрации сервиса IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Зарегистрирован"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Не зарегистрирован"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Недоступно"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 1ce6786..36fd952 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> සඳහා සැකසීම් විවෘත කිරීම අසාර්ථක විය"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"මෙම ආදාන ක්‍රමය මුරපද සහ ණයපත් අංක වැනි පෞද්ගලික දත්ත ඇතුළුව ඔබ ටයිප් කරන පෙළ එකතු කිරීමට හැකිය, එය <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> යෙදුමන් ලැබේ. මෙම ආදාන ක්‍රමය භාවිතා කරන්නද?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"සටහන: නැවත පණ ගැන්වීමකට පසුව, ඔබ ඔබේ දුරකථනය අගුලු හරින තෙක් මෙම යෙදුම ආරම්භ කළ නොහැකිය"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS ලියාපදිංචි තත්ත්වය"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"ලියාපදිංචි වී ඇත"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"ලියාපදිංචි වී නැත"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"ලබාගත නොහැක"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index b1d2fa3..2eea457 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Nastavenia aplikácie <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> sa nepodarilo otvoriť"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Pri tejto metóde vstupu sa môže zhromažďovať zadávaný text vrátane osobných údajov, ako sú heslá alebo čísla kreditných kariet. Táto metóda je poskytovaná aplikáciou <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Chcete použiť túto metódu vstupu?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Poznámka: Po reštartovaní sa táto aplikácia spustí až vtedy, keď odomknete telefón"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Stav registrácie IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrované"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Neregistrované"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Nie je k dispozícii"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 21badd6..e7e6212 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Ni mogoče odpreti nastavitev za <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Ta način vnosa lahko morda zbere besedilo, ki ga vtipkate, vključno z osebnimi podatki, kot so gesla in številke kreditnih kartic. Omogoča ga aplikacija <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Ali želite uporabiti ta način vnosa?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Opomba: po vnovičnem zagonu te aplikacije ni mogoče zagnati, če ne odklenete telefona."</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Stanje registracije IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrirana"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Ni registrirana"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Ni na voljo"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 54cde3c..f557d81 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Dështoi në hapjen e cilësimeve për <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Kjo metodë hyrjeje mund të mbledhë të gjithë tekstin që shkruan, përfshirë të dhënat personale si fjalëkalimet dhe numrat e kartave të kreditit. Kjo vjen nga aplikacioni <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Të përdoret kjo metodë hyrjeje?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Shënim: Pas një rinisjeje, ky aplikacion nuk mund të niset derisa të shkyçësh telefonin"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Gjendja e regjistrimit të IMS-së"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Regjistruar"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Paregjistruar"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Nuk ofrohet"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 4e0bee0..1c0fb24 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Отварање подешавања за апликацију <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> није успело"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Овај метод уноса можда може да прикупља сав текст који уносите, укључујући личне податке, као што су лозинке и бројеви кредитних картица. Потиче од апликације <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Желите ли да користите овај метод уноса?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Напомена: После рестартовања ова апликација не може да се покрене док не откључате телефон"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Статус IMS регистрације"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Регистрован je"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Није регистрован"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Недоступно"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index dea265d..c233bec 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Det gick inte att öppna inställningarna för <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Den här inmatningsmetoden kan samla all text som du skriver, inklusive personliga uppgifter som lösenord och kreditkortsnummer. Den kommer från appen <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Vill du använda inmatningsmetoden?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Obs! När du har startat om enheten måste du låsa upp mobilen innan du kan starta den här appen"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS-registrering"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registrerad"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Ej registrerad"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Inte tillgängligt"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 7126594..700153b 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Imeshindwa kufungua mipangilio ya <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Huenda mbinu hii ya kuingiza ikakusanya maandishi yote unayoandika, pamoja na data ya kibinafsi kama vile manenosiri na nambari za kadi za mkopo. Inatoka kwa programu <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Je, ungependa kutumia mbinu hii ya kingiza?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Kumbuka: Baada ya kuwasha tena programu hii, hutaweza kuitumia hadi utakapofungua simu yako"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Hali ya usajili wa IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Imesajiliwa"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Haijasajiliwa"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Hapatikani"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 4f563fa..5ea41c4 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> க்கான அமைப்புகளைத் திறப்பதில் தோல்வி"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"இந்த உள்ளீட்டு முறையானது, கடவுச்சொற்கள் மற்றும் கிரெடிட் கார்டு எண்கள் போன்ற தனிப்பட்ட தகவல் உள்பட நீங்கள் உள்ளிடும் எல்லா உரையையும் சேகரிக்கக்கூடும். இது <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> பயன்பாட்டிலிருந்து வந்துள்ளது. இந்த உள்ளீட்டு முறையைப் பயன்படுத்தவா?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"குறிப்பு: மறுதொடக்கம் செய்த பிறகு, மொபைலைத் திறக்கும் வரை இந்தப் பயன்பாட்டால் தொடங்க முடியாது"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS பதிவின் நிலை"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"பதிவு செய்யப்பட்டது"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"பதிவு செய்யப்படவில்லை"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"கிடைக்கவில்லை"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 0d1ca375..7daa89e 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> యొక్క సెట్టింగ్‌లను తెరవడం విఫలమైంది"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ఈ ఇన్‌పుట్ పద్ధతి మీరు టైప్ చేసే మొత్తం వచనాన్ని అలాగే పాస్‌వర్డ్‌లు మరియు క్రెడిట్ కార్డు నంబర్‌ల వంటి వ్యక్తిగత డేటాను సేకరించగలదు. ఇది <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> అనువర్తనంలో అందించబడుతుంది. ఈ ఇన్‌పుట్ పద్ధతిని ఉపయోగించాలా?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"గమనిక: రీబూట్ చేసాక, మీరు మీ ఫోన్‌ను అన్‌లాక్ చేసే వరకు ఈ యాప్ ప్రారంభం కాదు"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS నమోదు స్థితి"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"నమోదు చేయబడింది"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"నమోదు కాలేదు"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"అందుబాటులో లేదు"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index f7ba20a..37fba990 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"ไม่สามารถเปิดการตั้งค่าสำหรับ <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"วิธีการป้อนข้อมูลนี้อาจเก็บข้อความทั้งหมดที่คุณพิมพ์ รวมถึงข้อมูลส่วนบุคคล เช่น รหัสผ่านและหมายเลขบัตรเครดิต โดยมาจากแอปพลิเคชัน <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ใช้วิธีการป้อนข้อมูลนี้หรือไม่"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"หมายเหตุ: หลังจากเริ่มต้นใหม่ แอปนี้จะไม่สามารถเริ่มการทำงานได้จนกว่าคุณจะปลดล็อกโทรศัพท์"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"สถานะการลงทะเบียน IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"ลงทะเบียนแล้ว"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"ไม่ได้ลงทะเบียน"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"ไม่ว่าง"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 10d8102..25227a3 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Nabigong buksan ang mga setting para sa <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Maaaring magawa ng pamamaraan ng pag-input na ito na kolektahin ang lahat ng tekstong iyong tina-type, kabilang ang personal na data katulad ng mga password at mga numero ng credit card. Nagmumula ito sa app na <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Gamitin ang pamamaraan ng pag-input na ito?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Tandaan: Pagkatapos ng pag-reboot, hindi makakapagsimula ang app na ito hangga\'t hindi mo ina-unlock ang iyong telepono"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Status ng pagpaparehistro ng IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Nakarehistro"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Hindi nakarehistro"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Hindi available"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 3d8d0d3..893d8b3 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> ayarları açılamadı"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Bu giriş yöntemi, şifreler ve kredi kartı numaraları gibi kişisel veriler de dahil olmak üzere yazdığınız tüm metni toplayabilir. Bu yöntem, <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> uygulamasının bir özelliğidir. Bu giriş yöntemini kullanmak istiyor musunuz?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Not: Yeniden başlatma sonrasında, telefonunuzun kilidi açılıncaya kadar bu uygulama başlatılamaz"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS kaydı durumu"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Kaydettirildi"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Kaydettirilmedi"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Kullanılamıyor"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 7d2c6fd..f3ed643 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Не вдалося відкрити налаштування для програми <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Під час використання цього методу введення може записуватись весь текст, який ви вводите, зокрема паролі й номери кредитних карток. Цей метод запитує програма <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Використати цей метод введення?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Примітка: щоб запустити цей додаток після перезавантаження, спершу потрібно буде розблокувати телефон"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Статус реєстрації IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Зареєстровано"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Не зареєстровано"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Недоступно"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 63c040e..550280d 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> کیلئے ترتیبات کھولنے میں ناکام ہوگیا"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"اندراج کا یہ طریقہ آپ کے ٹائپ کردہ سبھی متن کو جمع کر سکتا ہے، بشمول ذاتی ڈیٹا جیسے پاس ورڈز اور کریڈٹ کارڈ نمبرز۔ یہ <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ایپ سے آتا ہے۔ اندراج کا یہ طریقہ استعمال کریں؟"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"نوٹ: ریبوٹ کرنے کے بعد یہ ایپ تب تک شروع نہیں ہو سکتی جب تک آپ اپنا فون غیر مقفل نہ کر لیں"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"‏IMS رجسٹریشن کی صورتحال"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"رجسٹر شدہ"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"رجسٹر نہیں ہے"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"غیر دستیاب"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index fbe9026..055613b 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> sozlamalarini ochmadi"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Ushbu yozish usuli barcha yozgan matnlaringizni to‘plab olishi mumkin, jumladan kredit karta raqamlari va parollar kabi shaxsiy ma‘lumotlarni ham. Usul  <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ilovasi bilan o‘rnatiladi. Ushbu usuldan foydalanilsinmi?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Eslatma: O‘chirib-yoqilgandan so‘ng, bu ilova to telefoningiz qulfdan chiqarilmaguncha ishga tushmaydi"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS registratsiyasi holati"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Registratsiya qilingan"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Registratsiya qilinmagan"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Mavjud emas"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 07d0999..bc5df8f 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Không thể mở cài đặt cho <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Phương thức nhập này có thể thu thập tất cả văn bản bạn nhập, bao gồm dữ liệu cá nhân như mật khẩu và số thẻ tín dụng. Phương thức nhập này đến từ ứng dụng <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Sử dụng phương thức nhập này?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Lưu ý: Sau khi khởi động lại, ứng dụng này không thể khởi động cho đến khi bạn mở khóa điện thoại"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Trạng thái đăng ký IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Đã đăng ký"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Chưa được đăng ký"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Không có"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 1850f61..4bbc976 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"无法打开 <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> 的设置"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"此输入法可能会收集您输入的所有内容,包括密码和信用卡号等个人数据。它来自“<xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>”应用。要使用此输入法吗?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"注意:重新启动后,您必须将手机解锁才能运行此应用"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS 注册状态"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"已注册"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"未注册"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"无法获取"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 379a1f1..e70b63b 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"無法開啟 <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> 的設定"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"這個輸入法可能會收集您輸入的所有文字,包括密碼和信用卡號碼等個人資料。這個輸入法由 <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> 應用程式提供,您要使用嗎?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"注意:重新啟動後,您必須解鎖手機,才可開始使用此應用程式"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS 註冊狀態"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"已註冊"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"未註冊"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"無法使用"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 2abca68..38ec6c7 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"無法開啟「<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>」的設定"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"這個輸入法是由「<xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>」應用程式所提供,它可能會收集你輸入的所有文字,包括密碼和信用卡號等個人資料。要啟用這個輸入法嗎?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"注意:重新啟動後,你必須將手機解鎖,才能執行這個應用程式"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS 註冊狀態"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"已註冊"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"未註冊"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"無法取得"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 1de1312..1c15d54 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -388,4 +388,8 @@
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Yehlulekile ukuvula izilungiselelo ze-<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"Indlela yokufakwayo ingase ikwazi ukuqoqa wonke umbhalo owuthayiphayo, kuhlanganise idatha yomuntu siqu njengamaphasiwedi nezinombolo zekhadi lesikoloto. Iphuma kuhlelo lokusebenza <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Sebenzisa indlela yokufaka?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Yazi: Ngemuva kokuqalisa, lolu hlelo lokusebenza alukwazi ukuqala uze uvule ifoni yakho"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"Isimo sokubhaliswa se-IMS"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"Kubhalisiwe"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Akubhalisiwe"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"Ayitholakali"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index fbfa725..3d083b1 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -289,7 +289,8 @@
     <string name="launch_defaults_some">Some defaults set</string>
     <!-- Launch defaults preference summary with none set [CHAR LIMIT=40] -->
     <string name="launch_defaults_none">No defaults set</string>
-
+    <!-- DO NOT TRANSLATE Empty summary for dynamic preferences -->
+    <string name="summary_empty" translatable="false"></string>
     <!-- Text-To-Speech (TTS) settings --><skip />
     <!-- Name of the TTS package as listed by the package manager. -->
     <string name="tts_settings">Text-to-speech settings</string>
@@ -982,4 +983,14 @@
     <!-- [CHAR LIMIT=NONE] Dialog body explaining that the app just selected by the user will not work after a reboot until until after the user enters their credentials, such as a PIN or password. -->
     <string name="direct_boot_unaware_dialog_message">Note: After a reboot, this app can\'t start until you unlock your phone</string>
 
+    <!--Label of IMS registration header -->
+    <string name="ims_reg_title">"IMS registration state"</string>
+    <!--Used when IMS registration state is registered -->
+    <string name="ims_reg_status_registered">"Registered"</string>
+    <!--Used when IMS registration state is not registered -->
+    <string name="ims_reg_status_not_registered">"Not registered"</string>
+
+    <!-- About phone, status item value if the actual value is not available. -->
+    <string name="status_unavailable">Unavailable</string>
+
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java
index 47cbb77..6aae226 100644
--- a/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java
@@ -28,17 +28,20 @@
 import android.support.v7.preference.TwoStatePreference;
 import android.text.TextUtils;
 
-import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.ConfirmationDialogController;
 
-public abstract class AbstractEnableAdbPreferenceController extends AbstractPreferenceController
-        implements ConfirmationDialogController {
+public abstract class AbstractEnableAdbPreferenceController extends
+        DeveloperOptionsPreferenceController implements ConfirmationDialogController {
     private static final String KEY_ENABLE_ADB = "enable_adb";
     public static final String ACTION_ENABLE_ADB_STATE_CHANGED =
             "com.android.settingslib.development.AbstractEnableAdbController."
                     + "ENABLE_ADB_STATE_CHANGED";
 
-    private SwitchPreference mPreference;
+    public static final int ADB_SETTING_ON = 1;
+    public static final int ADB_SETTING_OFF = 0;
+
+
+    protected SwitchPreference mPreference;
 
     public AbstractEnableAdbPreferenceController(Context context) {
         super(context);
@@ -64,12 +67,13 @@
 
     private boolean isAdbEnabled() {
         final ContentResolver cr = mContext.getContentResolver();
-        return Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) != 0;
+        return Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, ADB_SETTING_OFF)
+                != ADB_SETTING_OFF;
     }
 
     @Override
     public void updateState(Preference preference) {
-        ((TwoStatePreference)preference).setChecked(isAdbEnabled());
+        ((TwoStatePreference) preference).setChecked(isAdbEnabled());
     }
 
     public void enablePreference(boolean enabled) {
@@ -105,7 +109,7 @@
 
     protected void writeAdbSetting(boolean enabled) {
         Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.ADB_ENABLED, enabled ? 1 : 0);
+                Settings.Global.ADB_ENABLED, enabled ? ADB_SETTING_ON : ADB_SETTING_OFF);
         notifyStateChanged();
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogdSizePreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogdSizePreferenceController.java
index c167723..f79be7e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogdSizePreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogdSizePreferenceController.java
@@ -26,29 +26,34 @@
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settingslib.R;
-import com.android.settingslib.core.AbstractPreferenceController;
 
-public abstract class AbstractLogdSizePreferenceController extends AbstractPreferenceController
-        implements Preference.OnPreferenceChangeListener {
+public abstract class AbstractLogdSizePreferenceController extends
+        DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener {
     public static final String ACTION_LOGD_SIZE_UPDATED = "com.android.settingslib.development."
             + "AbstractLogdSizePreferenceController.LOGD_SIZE_UPDATED";
     public static final String EXTRA_CURRENT_LOGD_VALUE = "CURRENT_LOGD_VALUE";
 
+    @VisibleForTesting
+    static final String LOW_RAM_CONFIG_PROPERTY_KEY = "ro.config.low_ram";
     private static final String SELECT_LOGD_SIZE_KEY = "select_logd_size";
     @VisibleForTesting
     static final String SELECT_LOGD_SIZE_PROPERTY = "persist.logd.size";
     static final String SELECT_LOGD_TAG_PROPERTY = "persist.log.tag";
     // Tricky, isLoggable only checks for first character, assumes silence
     static final String SELECT_LOGD_TAG_SILENCE = "Settings";
-    private static final String SELECT_LOGD_SNET_TAG_PROPERTY = "persist.log.tag.snet_event_log";
+    @VisibleForTesting
+    static final String SELECT_LOGD_SNET_TAG_PROPERTY = "persist.log.tag.snet_event_log";
     private static final String SELECT_LOGD_RUNTIME_SNET_TAG_PROPERTY = "log.tag.snet_event_log";
     private static final String SELECT_LOGD_DEFAULT_SIZE_PROPERTY = "ro.logd.size";
     @VisibleForTesting
     static final String SELECT_LOGD_DEFAULT_SIZE_VALUE = "262144";
     private static final String SELECT_LOGD_SVELTE_DEFAULT_SIZE_VALUE = "65536";
     // 32768 is merely a menu marker, 64K is our lowest log buffer size we replace it with.
-    private static final String SELECT_LOGD_MINIMUM_SIZE_VALUE = "65536";
+    @VisibleForTesting
+    static final String SELECT_LOGD_MINIMUM_SIZE_VALUE = "65536";
     static final String SELECT_LOGD_OFF_SIZE_MARKER_VALUE = "32768";
+    @VisibleForTesting
+    static final String DEFAULT_SNET_TAG = "I";
 
     private ListPreference mLogdSize;
 
@@ -57,11 +62,6 @@
     }
 
     @Override
-    public boolean isAvailable() {
-        return true;
-    }
-
-    @Override
     public String getPreferenceKey() {
         return SELECT_LOGD_SIZE_KEY;
     }
@@ -160,7 +160,7 @@
             if ((snetValue == null) || (snetValue.length() == 0)) {
                 snetValue = SystemProperties.get(SELECT_LOGD_RUNTIME_SNET_TAG_PROPERTY);
                 if ((snetValue == null) || (snetValue.length() == 0)) {
-                    SystemProperties.set(SELECT_LOGD_SNET_TAG_PROPERTY, "I");
+                    SystemProperties.set(SELECT_LOGD_SNET_TAG_PROPERTY, DEFAULT_SNET_TAG);
                 }
             }
             // Silence all log sources, security logs notwithstanding
diff --git a/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogpersistPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogpersistPreferenceController.java
index 502fb17..67553adc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogpersistPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogpersistPreferenceController.java
@@ -30,16 +30,15 @@
 import android.text.TextUtils;
 
 import com.android.settingslib.R;
-import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.ConfirmationDialogController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnCreate;
 import com.android.settingslib.core.lifecycle.events.OnDestroy;
 
-public abstract class AbstractLogpersistPreferenceController extends AbstractPreferenceController
-        implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnCreate, OnDestroy,
-        ConfirmationDialogController {
+public abstract class AbstractLogpersistPreferenceController extends
+        DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener,
+        LifecycleObserver, OnCreate, OnDestroy, ConfirmationDialogController {
 
     private static final String SELECT_LOGPERSIST_KEY = "select_logpersist";
     private static final String SELECT_LOGPERSIST_PROPERTY = "persist.logd.logpersistd";
diff --git a/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java
new file mode 100644
index 0000000..f68c04f
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 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.settingslib.development;
+
+import android.content.Context;
+
+import com.android.settingslib.core.AbstractPreferenceController;
+
+/**
+ * This controller is used handle changes for the master switch in the developer options page.
+ *
+ * All Preference Controllers that are a part of the developer options page should inherit this
+ * class.
+ */
+public abstract class DeveloperOptionsPreferenceController extends
+        AbstractPreferenceController {
+
+    public DeveloperOptionsPreferenceController(Context context) {
+        super(context);
+    }
+
+    /**
+     * Child classes should override this method to create custom logic for hiding preferences.
+     *
+     * @return true if the preference is to be displayed.
+     */
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    /**
+     * Called when developer options is enabled
+     */
+    public void onDeveloperOptionsEnabled() {
+        if (isAvailable()) {
+            onDeveloperOptionsSwitchEnabled();
+        }
+    }
+
+    /**
+     * Called when developer options is disabled
+     */
+    public void onDeveloperOptionsDisabled() {
+        if (isAvailable()) {
+            onDeveloperOptionsSwitchDisabled();
+        }
+    }
+
+    /**
+     * Called when developer options is enabled and the preference is available
+     */
+    protected void onDeveloperOptionsSwitchEnabled() {
+    }
+
+    /**
+     * Called when developer options is disabled and the preference is available
+     */
+    protected void onDeveloperOptionsSwitchDisabled() {
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractBluetoothAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractBluetoothAddressPreferenceController.java
new file mode 100644
index 0000000..ba358f8
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractBluetoothAddressPreferenceController.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import android.annotation.SuppressLint;
+import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.settingslib.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+/**
+ * Preference controller for bluetooth address
+ */
+public abstract class AbstractBluetoothAddressPreferenceController
+        extends AbstractConnectivityPreferenceController {
+
+    @VisibleForTesting
+    static final String KEY_BT_ADDRESS = "bt_address";
+
+    private static final String[] CONNECTIVITY_INTENTS = {
+            BluetoothAdapter.ACTION_STATE_CHANGED
+    };
+
+    private Preference mBtAddress;
+
+    public AbstractBluetoothAddressPreferenceController(Context context, Lifecycle lifecycle) {
+        super(context, lifecycle);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return BluetoothAdapter.getDefaultAdapter() != null;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_BT_ADDRESS;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mBtAddress = screen.findPreference(KEY_BT_ADDRESS);
+        updateConnectivity();
+    }
+
+    @Override
+    protected String[] getConnectivityIntents() {
+        return CONNECTIVITY_INTENTS;
+    }
+
+    @SuppressLint("HardwareIds")
+    @Override
+    protected void updateConnectivity() {
+        BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
+        if (bluetooth != null && mBtAddress != null) {
+            String address = bluetooth.isEnabled() ? bluetooth.getAddress() : null;
+            if (!TextUtils.isEmpty(address)) {
+                // Convert the address to lowercase for consistency with the wifi MAC address.
+                mBtAddress.setSummary(address.toLowerCase());
+            } else {
+                mBtAddress.setSummary(R.string.status_unavailable);
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractConnectivityPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractConnectivityPreferenceController.java
new file mode 100644
index 0000000..c6552f7
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractConnectivityPreferenceController.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.os.Message;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Base class for preference controllers which listen to connectivity broadcasts
+ */
+public abstract class AbstractConnectivityPreferenceController
+        extends AbstractPreferenceController implements LifecycleObserver, OnStart, OnStop {
+
+    private final BroadcastReceiver mConnectivityReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (ArrayUtils.contains(getConnectivityIntents(), action)) {
+                getHandler().sendEmptyMessage(EVENT_UPDATE_CONNECTIVITY);
+            }
+        }
+    };
+
+    private static final int EVENT_UPDATE_CONNECTIVITY = 600;
+
+    private Handler mHandler;
+
+    public AbstractConnectivityPreferenceController(Context context, Lifecycle lifecycle) {
+        super(context);
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    @Override
+    public void onStop() {
+        mContext.unregisterReceiver(mConnectivityReceiver);
+    }
+
+    @Override
+    public void onStart() {
+        final IntentFilter connectivityIntentFilter = new IntentFilter();
+        final String[] intents = getConnectivityIntents();
+        for (String intent : intents) {
+            connectivityIntentFilter.addAction(intent);
+        }
+
+        mContext.registerReceiver(mConnectivityReceiver, connectivityIntentFilter,
+                android.Manifest.permission.CHANGE_NETWORK_STATE, null);
+    }
+
+    protected abstract String[] getConnectivityIntents();
+
+    protected abstract void updateConnectivity();
+
+    private Handler getHandler() {
+        if (mHandler == null) {
+            mHandler = new ConnectivityEventHandler(this);
+        }
+        return mHandler;
+    }
+
+    private static class ConnectivityEventHandler extends Handler {
+        private WeakReference<AbstractConnectivityPreferenceController> mPreferenceController;
+
+        public ConnectivityEventHandler(AbstractConnectivityPreferenceController activity) {
+            mPreferenceController = new WeakReference<>(activity);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            AbstractConnectivityPreferenceController preferenceController
+                    = mPreferenceController.get();
+            if (preferenceController == null) {
+                return;
+            }
+
+            switch (msg.what) {
+                case EVENT_UPDATE_CONNECTIVITY:
+                    preferenceController.updateConnectivity();
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown message " + msg.what);
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java
new file mode 100644
index 0000000..bb8404b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.os.PersistableBundle;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import com.android.settingslib.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+/**
+ * Preference controller for IMS status
+ */
+public abstract class AbstractImsStatusPreferenceController
+        extends AbstractConnectivityPreferenceController {
+
+    @VisibleForTesting
+    static final String KEY_IMS_REGISTRATION_STATE = "ims_reg_state";
+
+    private static final String[] CONNECTIVITY_INTENTS = {
+            BluetoothAdapter.ACTION_STATE_CHANGED,
+            ConnectivityManager.CONNECTIVITY_ACTION,
+            WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+            WifiManager.NETWORK_STATE_CHANGED_ACTION,
+    };
+
+    private Preference mImsStatus;
+
+    public AbstractImsStatusPreferenceController(Context context,
+            Lifecycle lifecycle) {
+        super(context, lifecycle);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        CarrierConfigManager configManager = mContext.getSystemService(CarrierConfigManager.class);
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        PersistableBundle config = null;
+        if (configManager != null) {
+            config = configManager.getConfigForSubId(subId);
+        }
+        return config != null && config.getBoolean(
+                CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_IMS_REGISTRATION_STATE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mImsStatus = screen.findPreference(KEY_IMS_REGISTRATION_STATE);
+        updateConnectivity();
+    }
+
+    @Override
+    protected String[] getConnectivityIntents() {
+        return CONNECTIVITY_INTENTS;
+    }
+
+    @Override
+    protected void updateConnectivity() {
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        if (mImsStatus != null) {
+            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+            mImsStatus.setSummary((tm != null && tm.isImsRegistered(subId)) ?
+                    R.string.ims_reg_status_registered : R.string.ims_reg_status_not_registered);
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java
new file mode 100644
index 0000000..ded3022
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
+import android.net.wifi.WifiManager;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import java.net.InetAddress;
+import java.util.Iterator;
+
+/**
+ * Preference controller for IP address
+ */
+public abstract class AbstractIpAddressPreferenceController
+        extends AbstractConnectivityPreferenceController {
+
+    @VisibleForTesting
+    static final String KEY_IP_ADDRESS = "wifi_ip_address";
+
+    private static final String[] CONNECTIVITY_INTENTS = {
+            ConnectivityManager.CONNECTIVITY_ACTION,
+            WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+            WifiManager.NETWORK_STATE_CHANGED_ACTION,
+    };
+
+    private Preference mIpAddress;
+    private final ConnectivityManager mCM;
+
+    public AbstractIpAddressPreferenceController(Context context, Lifecycle lifecycle) {
+        super(context, lifecycle);
+        mCM = context.getSystemService(ConnectivityManager.class);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_IP_ADDRESS;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mIpAddress = screen.findPreference(KEY_IP_ADDRESS);
+        updateConnectivity();
+    }
+
+    @Override
+    protected String[] getConnectivityIntents() {
+        return CONNECTIVITY_INTENTS;
+    }
+
+    @Override
+    protected void updateConnectivity() {
+        String ipAddress = getDefaultIpAddresses(mCM);
+        if (ipAddress != null) {
+            mIpAddress.setSummary(ipAddress);
+        } else {
+            mIpAddress.setSummary(R.string.status_unavailable);
+        }
+    }
+
+    /**
+     * Returns the default link's IP addresses, if any, taking into account IPv4 and IPv6 style
+     * addresses.
+     * @param cm ConnectivityManager
+     * @return the formatted and newline-separated IP addresses, or null if none.
+     */
+    private static String getDefaultIpAddresses(ConnectivityManager cm) {
+        LinkProperties prop = cm.getActiveLinkProperties();
+        return formatIpAddresses(prop);
+    }
+
+    private static String formatIpAddresses(LinkProperties prop) {
+        if (prop == null) return null;
+        Iterator<InetAddress> iter = prop.getAllAddresses().iterator();
+        // If there are no entries, return null
+        if (!iter.hasNext()) return null;
+        // Concatenate all available addresses, newline separated
+        StringBuilder addresses = new StringBuilder();
+        while (iter.hasNext()) {
+            addresses.append(iter.next().getHostAddress());
+            if (iter.hasNext()) addresses.append("\n");
+        }
+        return addresses.toString();
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractUptimePreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractUptimePreferenceController.java
new file mode 100644
index 0000000..ac61ade
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractUptimePreferenceController.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.format.DateUtils;
+
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Preference controller for uptime
+ */
+public abstract class AbstractUptimePreferenceController extends AbstractPreferenceController
+        implements LifecycleObserver, OnStart, OnStop {
+
+    @VisibleForTesting
+    static final String KEY_UPTIME = "up_time";
+    private static final int EVENT_UPDATE_STATS = 500;
+
+    private Preference mUptime;
+    private Handler mHandler;
+
+    public AbstractUptimePreferenceController(Context context, Lifecycle lifecycle) {
+        super(context);
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    @Override
+    public void onStart() {
+        getHandler().sendEmptyMessage(EVENT_UPDATE_STATS);
+    }
+
+    @Override
+    public void onStop() {
+        getHandler().removeMessages(EVENT_UPDATE_STATS);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_UPTIME;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mUptime = screen.findPreference(KEY_UPTIME);
+        updateTimes();
+    }
+
+    private Handler getHandler() {
+        if (mHandler == null) {
+            mHandler = new MyHandler(this);
+        }
+        return mHandler;
+    }
+
+    private void updateTimes() {
+        mUptime.setSummary(DateUtils.formatDuration(SystemClock.elapsedRealtime()));
+    }
+
+    private static class MyHandler extends Handler {
+        private WeakReference<AbstractUptimePreferenceController> mStatus;
+
+        public MyHandler(AbstractUptimePreferenceController activity) {
+            mStatus = new WeakReference<>(activity);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            AbstractUptimePreferenceController status = mStatus.get();
+            if (status == null) {
+                return;
+            }
+
+            switch (msg.what) {
+                case EVENT_UPDATE_STATS:
+                    status.updateTimes();
+                    sendEmptyMessageDelayed(EVENT_UPDATE_STATS, 1000);
+                    break;
+
+                default:
+                    throw new IllegalStateException("Unknown message " + msg.what);
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
new file mode 100644
index 0000000..d57b64f
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.settingslib.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+/**
+ * Preference controller for WIFI MAC address
+ */
+public abstract class AbstractWifiMacAddressPreferenceController
+        extends AbstractConnectivityPreferenceController {
+
+    @VisibleForTesting
+    static final String KEY_WIFI_MAC_ADDRESS = "wifi_mac_address";
+
+    private static final String[] CONNECTIVITY_INTENTS = {
+            ConnectivityManager.CONNECTIVITY_ACTION,
+            WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+            WifiManager.NETWORK_STATE_CHANGED_ACTION,
+    };
+
+    private Preference mWifiMacAddress;
+    private final WifiManager mWifiManager;
+
+    public AbstractWifiMacAddressPreferenceController(Context context, Lifecycle lifecycle) {
+        super(context, lifecycle);
+        mWifiManager = context.getSystemService(WifiManager.class);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_WIFI_MAC_ADDRESS;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mWifiMacAddress = screen.findPreference(KEY_WIFI_MAC_ADDRESS);
+        updateConnectivity();
+    }
+
+    @Override
+    protected String[] getConnectivityIntents() {
+        return CONNECTIVITY_INTENTS;
+    }
+
+    @SuppressLint("HardwareIds")
+    @Override
+    protected void updateConnectivity() {
+        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+        String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
+        if (!TextUtils.isEmpty(macAddress)) {
+            mWifiMacAddress.setSummary(macAddress);
+        } else {
+            mWifiMacAddress.setSummary(R.string.status_unavailable);
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
index 56b8441..9c34763 100644
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
@@ -261,7 +261,7 @@
         if (requiredAccountType == null) {
             return true;
         }
-        AccountManager accountManager = AccountManager.get(mContext);
+        AccountManager accountManager = mContext.getSystemService(AccountManager.class);
         Account[] accounts = accountManager.getAccountsByType(requiredAccountType);
         boolean satisfiesRequiredAccount = accounts.length > 0;
         if (!satisfiesRequiredAccount) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 12455d8..c56e1da 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -291,15 +291,6 @@
     }
 
     /**
-     * Force a scan for wifi networks to happen now.
-     */
-    public void forceScan() {
-        if (mWifiManager.isWifiEnabled() && mScanner != null) {
-            mScanner.forceScan();
-        }
-    }
-
-    /**
      * Temporarily stop scanning for wifi networks.
      */
     public void pauseScanning() {
@@ -789,14 +780,6 @@
         }
     }
 
-    public static List<AccessPoint> getCurrentAccessPoints(Context context, boolean includeSaved,
-            boolean includeScans) {
-        WifiTracker tracker = new WifiTracker(context, null, includeSaved, includeScans);
-        tracker.forceUpdate();
-        tracker.copyAndNotifyListeners(false /*notifyListeners*/);
-        return tracker.getAccessPoints();
-    }
-
     @VisibleForTesting
     final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
@@ -986,11 +969,6 @@
             }
         }
 
-        void forceScan() {
-            removeMessages(MSG_SCAN);
-            sendEmptyMessage(MSG_SCAN);
-        }
-
         void pause() {
             mRetry = 0;
             removeMessages(MSG_SCAN);
diff --git a/packages/SettingsLib/tests/robotests/Android.mk b/packages/SettingsLib/tests/robotests/Android.mk
index 55b635e..bc1a834 100644
--- a/packages/SettingsLib/tests/robotests/Android.mk
+++ b/packages/SettingsLib/tests/robotests/Android.mk
@@ -42,11 +42,12 @@
 # Include the testing libraries (JUnit4 + Robolectric libs).
 LOCAL_STATIC_JAVA_LIBRARIES := \
     mockito-robolectric-prebuilt \
+    platform-robolectric-android-all-stubs \
     truth-prebuilt
 
 LOCAL_JAVA_LIBRARIES := \
     junit \
-    platform-robolectric-prebuilt
+    platform-robolectric-3.4.2-prebuilt
 
 LOCAL_INSTRUMENTATION_FOR := SettingsLibShell
 LOCAL_MODULE := SettingsLibRoboTests
@@ -69,4 +70,6 @@
 
 LOCAL_TEST_PACKAGE := SettingsLibShell
 
-include prebuilts/misc/common/robolectric/run_robotests.mk
+LOCAL_ROBOTEST_TIMEOUT := 36000
+
+include prebuilts/misc/common/robolectric/3.4.2/run_robotests.mk
diff --git a/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java b/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java
deleted file mode 100644
index abccd8d..0000000
--- a/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2017 Google Inc.
- *
- * 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 android.net.wifi;
-
-import android.content.Context;
-import android.os.Handler;
-
-import java.util.List;
-
-/**
- * Will be removed once robolectric is updated to O
- */
-public class WifiNetworkScoreCache {
-
-    public WifiNetworkScoreCache(Context context, WifiNetworkScoreCache.CacheListener listener) {
-    }
-
-    public abstract static class CacheListener {
-        public CacheListener(Handler handler) {
-        }
-
-        void post(List updatedNetworks) {
-        }
-
-        public abstract void networkCacheUpdated(List updatedNetworks);
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
index c3a505a..ca366ea 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
@@ -20,8 +20,11 @@
 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT;
 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
@@ -56,10 +59,10 @@
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private RestrictedLockUtils.Proxy mProxy;
 
-    private static final int mUserId = 194;
-    private static final int mProfileId = 160;
-    private static final ComponentName mAdmin1 = new ComponentName("admin1", "admin1class");
-    private static final ComponentName mAdmin2 = new ComponentName("admin2", "admin2class");
+    private final int mUserId = 194;
+    private final int mProfileId = 160;
+    private final ComponentName mAdmin1 = new ComponentName("admin1", "admin1class");
+    private final ComponentName mAdmin2 = new ComponentName("admin2", "admin2class");
 
     @Before
     public void setUp() {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
index 8099eb1..698e442 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
@@ -53,15 +53,15 @@
 
     static void getIncludedResourcePaths(String packageName, List<ResourcePath> paths) {
         paths.add(new ResourcePath(
-                packageName,
+                null,
                 Fs.fileFromPath("./frameworks/base/packages/SettingsLib/res"),
                 null));
         paths.add(new ResourcePath(
-                packageName,
+                null,
                 Fs.fileFromPath("./frameworks/base/core/res/res"),
                 null));
         paths.add(new ResourcePath(
-                packageName,
+                null,
                 Fs.fileFromPath("./frameworks/support/v7/appcompat/res"),
                 null));
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
index 31abecd..3af9768 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
@@ -17,7 +17,7 @@
 package com.android.settingslib;
 
 public class TestConfig {
-    public static final int SDK_VERSION = 23;
+    public static final int SDK_VERSION = 25;
     public static final String MANIFEST_PATH =
             "frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml";
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
index d6bca0e..1290391 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
@@ -35,9 +35,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.android.controller.FragmentController;
 import org.robolectric.annotation.Config;
-import org.robolectric.util.ActivityController;
-import org.robolectric.util.FragmentController;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -168,7 +168,7 @@
                 Robolectric.buildFragment(TestDialogFragment.class);
         TestDialogFragment fragment = fragmentController.get();
 
-        fragmentController.attach().create().start().resume();
+        fragmentController.create().start().resume();
         fragment.onCreateOptionsMenu(null, null);
         fragment.onPrepareOptionsMenu(null);
         fragment.onOptionsItemSelected(null);
@@ -192,7 +192,7 @@
                 Robolectric.buildFragment(TestFragment.class);
         TestFragment fragment = fragmentController.get();
 
-        fragmentController.attach().create().start().resume();
+        fragmentController.create().start().resume();
         fragment.onCreateOptionsMenu(null, null);
         fragment.onPrepareOptionsMenu(null);
         fragment.onOptionsItemSelected(null);
@@ -235,7 +235,7 @@
         OptionItemAccepter accepter = new OptionItemAccepter();
         fragment.getLifecycle().addObserver(accepter);
 
-        fragmentController.attach().create().start().resume();
+        fragmentController.create().start().resume();
         fragment.onCreateOptionsMenu(null, null);
         fragment.onPrepareOptionsMenu(null);
         fragment.onOptionsItemSelected(null);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogdSizePreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogdSizePreferenceControllerTest.java
index 94bfd8f..26d3570 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogdSizePreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogdSizePreferenceControllerTest.java
@@ -16,9 +16,29 @@
 
 package com.android.settingslib.development;
 
+import static com.android.settingslib.development.AbstractLogdSizePreferenceController
+        .DEFAULT_SNET_TAG;
+import static com.android.settingslib.development.AbstractLogdSizePreferenceController
+        .LOW_RAM_CONFIG_PROPERTY_KEY;
+import static com.android.settingslib.development.AbstractLogdSizePreferenceController
+        .SELECT_LOGD_MINIMUM_SIZE_VALUE;
+import static com.android.settingslib.development.AbstractLogdSizePreferenceController
+        .SELECT_LOGD_OFF_SIZE_MARKER_VALUE;
+import static com.android.settingslib.development.AbstractLogdSizePreferenceController
+        .SELECT_LOGD_SIZE_PROPERTY;
+import static com.android.settingslib.development.AbstractLogdSizePreferenceController
+        .SELECT_LOGD_SNET_TAG_PROPERTY;
+import static com.android.settingslib.development.AbstractLogdSizePreferenceController
+        .SELECT_LOGD_TAG_PROPERTY;
+import static com.android.settingslib.development.AbstractLogdSizePreferenceController
+        .SELECT_LOGD_TAG_SILENCE;
+
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
+import android.content.Context;
 import android.os.SystemProperties;
 import android.support.v7.preference.ListPreference;
 import android.support.v7.preference.PreferenceScreen;
@@ -27,6 +47,7 @@
 import com.android.settingslib.SettingsLibRobolectricTestRunner;
 import com.android.settingslib.TestConfig;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -45,22 +66,43 @@
     @Mock
     private PreferenceScreen mPreferenceScreen;
 
+    /**
+     * List Values
+     *
+     * 0: off
+     * 1: 64k
+     * 2: 256k
+     * 3: 1M
+     * 4: 4M
+     * 5: 16M
+     */
+    private String[] mListValues;
+    private String[] mListSummaries;
+    private Context mContext;
     private AbstractLogdSizePreferenceController mController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mController = new AbstractLogdSizePreferenceController(RuntimeEnvironment.application) {};
-
+        mContext = RuntimeEnvironment.application;
+        mController = new AbstractLogdSizePreferenceController(RuntimeEnvironment.application) {
+        };
+        mListValues = mContext.getResources().getStringArray(R.array.select_logd_size_values);
+        mListSummaries = mContext.getResources().getStringArray(R.array.select_logd_size_summaries);
         doReturn(mListPreference).when(mPreferenceScreen)
                 .findPreference(mController.getPreferenceKey());
 
         mController.displayPreference(mPreferenceScreen);
     }
 
+    @After
+    public void tearDown() {
+        SystemPropertiesTestImpl.clear();
+    }
+
     @Test
-    public void testUpateLogdSizeValues_lowRamEntries() {
-        SystemProperties.set("ro.config.low_ram", "true");
+    public void testUpdateLogdSizeValues_lowRamEntries() {
+        SystemProperties.set(LOW_RAM_CONFIG_PROPERTY_KEY, "true");
         mController.updateLogdSizeValues();
         verify(mListPreference).setEntries(R.array.select_logd_size_lowram_titles);
     }
@@ -77,4 +119,79 @@
         verify(mListPreference).setValue(
                 AbstractLogdSizePreferenceController.SELECT_LOGD_OFF_SIZE_MARKER_VALUE);
     }
+
+    @Test
+    public void onPreferenceChange_noTagsSizeValueOff_shouldSetTagAndSnetTagAndSet64KSize() {
+        mController.onPreferenceChange(mListPreference, SELECT_LOGD_OFF_SIZE_MARKER_VALUE);
+
+        final String tag = SystemProperties.get(SELECT_LOGD_TAG_PROPERTY);
+        final String logSize = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
+        final String snetTag = SystemProperties.get(SELECT_LOGD_SNET_TAG_PROPERTY);
+
+        assertThat(tag).isEqualTo(SELECT_LOGD_TAG_SILENCE);
+        assertThat(logSize).isEqualTo(SELECT_LOGD_MINIMUM_SIZE_VALUE);
+        assertThat(snetTag).isEqualTo(DEFAULT_SNET_TAG);
+    }
+
+    @Test
+    public void onPreferenceChange_noTagsSizeValue64K_shouldNotSetTagAndSet64KSize() {
+        mController.onPreferenceChange(mListPreference, SELECT_LOGD_MINIMUM_SIZE_VALUE);
+
+        final String tag = SystemProperties.get(SELECT_LOGD_TAG_PROPERTY);
+        final String logSize = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
+        final String snetTag = SystemProperties.get(SELECT_LOGD_SNET_TAG_PROPERTY);
+
+        assertThat(tag).isEmpty();
+        assertThat(logSize).isEqualTo(SELECT_LOGD_MINIMUM_SIZE_VALUE);
+        assertThat(snetTag).isEmpty();
+    }
+
+    @Test
+    public void onPreferenceChange_set1M_shouldUpdateSettingLogSizeTo1M() {
+        mController.onPreferenceChange(mListPreference, mListValues[3]);
+
+        final String logSize = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
+
+        assertThat(logSize).isEqualTo(mListValues[3]);
+    }
+
+    @Test
+    public void onPreferenceChange_noValue_shouldUpdateSettingToEmpty() {
+        mController.onPreferenceChange(mListPreference, "" /* new value */);
+
+        final String logSize = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
+
+        assertThat(logSize).isEmpty();
+    }
+
+    @Test
+    public void updateLogdSizeValues_noValueSet_shouldSetDefaultTo64K() {
+        SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, "" /* new value */);
+
+        mController.updateLogdSizeValues();
+
+        verify(mListPreference).setValue(mListValues[2]);
+        verify(mListPreference).setSummary(mListSummaries[2]);
+    }
+
+    @Test
+    public void updateLogdSizeValues_noValueSetLowRamSet_shouldSetDefaultTo64K() {
+        SystemProperties.set(LOW_RAM_CONFIG_PROPERTY_KEY, Boolean.toString(true));
+        SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, "" /* new value */);
+
+        mController.updateLogdSizeValues();
+
+        verify(mListPreference).setValue(mListValues[1]);
+        verify(mListPreference).setSummary(mListSummaries[1]);
+    }
+
+    @Test
+    public void updateLogdSizeValues_64KSet_shouldSet64K() {
+        SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, mListValues[1]);
+
+        mController.updateLogdSizeValues();
+
+        verify(mListPreference).setValue(mListValues[1]);
+        verify(mListPreference).setSummary(mListSummaries[1]);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropertiesTestImpl.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropertiesTestImpl.java
index 2f89d86..6977e09 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropertiesTestImpl.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropertiesTestImpl.java
@@ -54,4 +54,8 @@
     public static void set(String key, String val) {
         sProperties.put(key, val);
     }
+
+    public static synchronized void clear() {
+        sProperties.clear();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/BluetoothAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/BluetoothAddressPreferenceControllerTest.java
new file mode 100644
index 0000000..1de7a7a
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/BluetoothAddressPreferenceControllerTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.Mockito.doReturn;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BluetoothAddressPreferenceControllerTest {
+    @Mock
+    private Context mContext;
+    @Mock
+    private Lifecycle mLifecycle;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private Preference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mPreference).when(mScreen)
+                .findPreference(AbstractBluetoothAddressPreferenceController.KEY_BT_ADDRESS);
+    }
+
+    @Implements(BluetoothAdapter.class)
+    public static class ShadowEmptyBluetoothAdapter {
+        @Implementation
+        public static BluetoothAdapter getDefaultAdapter() {
+            return null;
+        }
+    }
+
+    @Test
+    @Config(shadows = ShadowEmptyBluetoothAdapter.class)
+    public void testNoBluetooth() {
+        final AbstractBluetoothAddressPreferenceController bluetoothAddressPreferenceController =
+                new ConcreteBluetoothAddressPreferenceController(mContext, mLifecycle);
+
+        assertWithMessage("Should not show pref if no bluetooth")
+                .that(bluetoothAddressPreferenceController.isAvailable())
+                .isFalse();
+    }
+
+    @Test
+    public void testHasBluetooth() {
+        final AbstractBluetoothAddressPreferenceController bluetoothAddressPreferenceController =
+                new ConcreteBluetoothAddressPreferenceController(mContext, mLifecycle);
+
+        assertWithMessage("Should show pref if bluetooth is present")
+                .that(bluetoothAddressPreferenceController.isAvailable())
+                .isTrue();
+    }
+
+    @Test
+    public void testHasBluetoothStateChangedFilter() {
+        final AbstractBluetoothAddressPreferenceController bluetoothAddressPreferenceController =
+                new ConcreteBluetoothAddressPreferenceController(mContext, mLifecycle);
+
+        assertWithMessage("Filter should have BluetoothAdapter.ACTION_STATE_CHANGED")
+                .that(bluetoothAddressPreferenceController.getConnectivityIntents())
+                .asList().contains(BluetoothAdapter.ACTION_STATE_CHANGED);
+    }
+
+    private static class ConcreteBluetoothAddressPreferenceController
+            extends AbstractBluetoothAddressPreferenceController {
+
+        public ConcreteBluetoothAddressPreferenceController(Context context,
+                Lifecycle lifecycle) {
+            super(context, lifecycle);
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ConnectivityPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ConnectivityPreferenceControllerTest.java
new file mode 100644
index 0000000..362dbd9
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ConnectivityPreferenceControllerTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.IntentFilter;
+import android.os.Handler;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ConnectivityPreferenceControllerTest {
+    @Mock
+    private Context mContext;
+
+    @Mock
+    private Lifecycle mLifecycle;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testBroadcastReceiver() {
+        final AbstractConnectivityPreferenceController preferenceController =
+                spy(new ConcreteConnectivityPreferenceController(mContext, mLifecycle));
+
+        final ArgumentCaptor<BroadcastReceiver> receiverArgumentCaptor =
+                ArgumentCaptor.forClass(BroadcastReceiver.class);
+        final ArgumentCaptor<IntentFilter> filterArgumentCaptor =
+                ArgumentCaptor.forClass(IntentFilter.class);
+
+        doReturn(new String[] {"Filter1", "Filter2"})
+                .when(preferenceController).getConnectivityIntents();
+
+        preferenceController.onStart();
+
+        verify(mContext, times(1))
+                .registerReceiver(receiverArgumentCaptor.capture(),
+                        filterArgumentCaptor.capture(),
+                        anyString(), nullable(Handler.class));
+
+        final BroadcastReceiver receiver = receiverArgumentCaptor.getValue();
+        final IntentFilter filter = filterArgumentCaptor.getValue();
+
+        assertWithMessage("intent filter should match 'Filter1'")
+                .that(filter.matchAction("Filter1"))
+                .isTrue();
+        assertWithMessage("intent filter should match 'Filter2'")
+                .that(filter.matchAction("Filter2"))
+                .isTrue();
+
+        preferenceController.onStop();
+
+        verify(mContext, times(1)).unregisterReceiver(receiver);
+    }
+
+    private static class ConcreteConnectivityPreferenceController
+            extends AbstractConnectivityPreferenceController {
+
+
+        public ConcreteConnectivityPreferenceController(Context context,
+                Lifecycle lifecycle) {
+            super(context, lifecycle);
+        }
+
+        @Override
+        public boolean isAvailable() {
+            return false;
+        }
+
+        @Override
+        public String getPreferenceKey() {
+            return null;
+        }
+
+        @Override
+        protected String[] getConnectivityIntents() {
+            return new String[0];
+        }
+
+        @Override
+        protected void updateConnectivity() {
+
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ImsStatusPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ImsStatusPreferenceControllerTest.java
new file mode 100644
index 0000000..112ee64
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ImsStatusPreferenceControllerTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.os.PersistableBundle;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ImsStatusPreferenceControllerTest {
+    @Mock
+    private Context mContext;
+    @Mock
+    private Lifecycle mLifecycle;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private Preference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mPreference).when(mScreen)
+                .findPreference(AbstractImsStatusPreferenceController.KEY_IMS_REGISTRATION_STATE);
+    }
+
+    @Test
+    @Config(shadows = ShadowSubscriptionManager.class)
+    public void testIsAvailable() {
+        CarrierConfigManager carrierConfigManager = mock(CarrierConfigManager.class);
+        doReturn(carrierConfigManager).when(mContext).getSystemService(CarrierConfigManager.class);
+
+        PersistableBundle config = new PersistableBundle(1);
+        config.putBoolean(CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true);
+        doReturn(config).when(carrierConfigManager).getConfigForSubId(anyInt());
+
+        final AbstractImsStatusPreferenceController imsStatusPreferenceController =
+                new ConcreteImsStatusPreferenceController(mContext, mLifecycle);
+
+        assertWithMessage("Should be available when IMS registration is true").that(
+                imsStatusPreferenceController.isAvailable()).isTrue();
+
+        config.putBoolean(CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
+
+        assertWithMessage("Should not be available when IMS registration is false")
+                .that(imsStatusPreferenceController.isAvailable()).isFalse();
+
+        doReturn(null).when(carrierConfigManager).getConfigForSubId(anyInt());
+
+        assertWithMessage("Should not be available when IMS registration is false")
+                .that(imsStatusPreferenceController.isAvailable()).isFalse();
+
+        doReturn(null).when(mContext).getSystemService(CarrierConfigManager.class);
+
+        assertWithMessage("Should not be available when CarrierConfigManager service is null")
+                .that(imsStatusPreferenceController.isAvailable()).isFalse();
+    }
+
+    @Implements(SubscriptionManager.class)
+    public static class ShadowSubscriptionManager {
+        @Implementation
+        public static int getDefaultDataSubscriptionId() {
+            return 1234;
+        }
+    }
+
+    private static class ConcreteImsStatusPreferenceController
+            extends AbstractImsStatusPreferenceController {
+
+        public ConcreteImsStatusPreferenceController(Context context,
+                Lifecycle lifecycle) {
+            super(context, lifecycle);
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java
new file mode 100644
index 0000000..d0ecae3
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.Mockito.doReturn;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class IpAddressPreferenceControllerTest {
+    @Mock
+    private Context mContext;
+    @Mock
+    private Lifecycle mLifecycle;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private Preference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mPreference).when(mScreen)
+                .findPreference(AbstractIpAddressPreferenceController.KEY_IP_ADDRESS);
+    }
+
+    @Test
+    public void testHasIntentFilters() {
+        final AbstractIpAddressPreferenceController ipAddressPreferenceController =
+                new ConcreteIpAddressPreferenceController(mContext, mLifecycle);
+        final List<String> expectedIntents = Arrays.asList(
+                ConnectivityManager.CONNECTIVITY_ACTION,
+                WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+                WifiManager.NETWORK_STATE_CHANGED_ACTION);
+
+
+        assertWithMessage("Intent filter should contain expected intents")
+                .that(ipAddressPreferenceController.getConnectivityIntents())
+                .asList().containsAllIn(expectedIntents);
+    }
+
+    private static class ConcreteIpAddressPreferenceController extends
+            AbstractIpAddressPreferenceController {
+
+        public ConcreteIpAddressPreferenceController(Context context,
+                Lifecycle lifecycle) {
+            super(context, lifecycle);
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/UptimePreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/UptimePreferenceControllerTest.java
new file mode 100644
index 0000000..f68533b
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/UptimePreferenceControllerTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.SystemClock;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.format.DateUtils;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowLooper;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class UptimePreferenceControllerTest {
+    @Mock
+    private Context mContext;
+    @Mock
+    private Lifecycle mLifecycle;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private Preference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mPreference).when(mScreen)
+                .findPreference(AbstractUptimePreferenceController.KEY_UPTIME);
+    }
+
+    @Test
+    public void testDisplayPreference() {
+        final AbstractUptimePreferenceController uptimePreferenceController =
+                new ConcreteUptimePreferenceController(mContext, mLifecycle);
+
+        uptimePreferenceController.displayPreference(mScreen);
+
+        // SystemClock is shadowed so it shouldn't advance unexpectedly while the test is running
+        verify(mPreference).setSummary(DateUtils.formatDuration(SystemClock.elapsedRealtime()));
+    }
+
+    @Test
+    public void testUptimeTick() {
+        final AbstractUptimePreferenceController uptimePreferenceController =
+                new ConcreteUptimePreferenceController(mContext, null /* lifecycle */);
+
+        uptimePreferenceController.displayPreference(mScreen);
+
+        verify(mPreference, times(1)).setSummary(any(CharSequence.class));
+
+        uptimePreferenceController.onStart();
+
+        verify(mPreference, times(2)).setSummary(any(CharSequence.class));
+
+        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+
+        verify(mPreference, times(3)).setSummary(any(CharSequence.class));
+
+        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+
+        verify(mPreference, times(4)).setSummary(any(CharSequence.class));
+    }
+
+    private static class ConcreteUptimePreferenceController
+            extends AbstractUptimePreferenceController {
+        public ConcreteUptimePreferenceController(Context context,
+                Lifecycle lifecycle) {
+            super(context, lifecycle);
+        }
+    }
+
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
new file mode 100644
index 0000000..265a60b
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 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.settingslib.deviceinfo;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.R;
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import java.util.Arrays;
+import java.util.List;
+
+@SuppressLint("HardwareIds")
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class WifiMacAddressPreferenceControllerTest {
+    @Mock
+    private Context mContext;
+    @Mock
+    private Lifecycle mLifecycle;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private Preference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mPreference).when(mScreen)
+                .findPreference(AbstractWifiMacAddressPreferenceController.KEY_WIFI_MAC_ADDRESS);
+    }
+
+    @Test
+    public void testHasIntentFilters() {
+        final AbstractWifiMacAddressPreferenceController wifiMacAddressPreferenceController =
+                new ConcreteWifiMacAddressPreferenceController(mContext, mLifecycle);
+        final List<String> expectedIntents = Arrays.asList(
+                ConnectivityManager.CONNECTIVITY_ACTION,
+                WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+                WifiManager.NETWORK_STATE_CHANGED_ACTION);
+
+
+        assertWithMessage("Intent filter should contain expected intents")
+                .that(wifiMacAddressPreferenceController.getConnectivityIntents())
+                .asList().containsAllIn(expectedIntents);
+    }
+
+    @Test
+    public void testWifiMacAddress() {
+        final WifiManager wifiManager = mock(WifiManager.class);
+        final WifiInfo wifiInfo = mock(WifiInfo.class);
+        doReturn("00:11:22:33:44:55").when(wifiInfo).getMacAddress();
+
+        doReturn(null).when(wifiManager).getConnectionInfo();
+        doReturn(wifiManager).when(mContext).getSystemService(WifiManager.class);
+
+        final AbstractWifiMacAddressPreferenceController wifiMacAddressPreferenceController =
+                new ConcreteWifiMacAddressPreferenceController(mContext, mLifecycle);
+
+        wifiMacAddressPreferenceController.displayPreference(mScreen);
+
+        verify(mPreference).setSummary(R.string.status_unavailable);
+
+        doReturn(wifiInfo).when(wifiManager).getConnectionInfo();
+
+        wifiMacAddressPreferenceController.displayPreference(mScreen);
+
+        verify(mPreference).setSummary("00:11:22:33:44:55");
+    }
+
+    private static class ConcreteWifiMacAddressPreferenceController
+            extends AbstractWifiMacAddressPreferenceController {
+
+        public ConcreteWifiMacAddressPreferenceController(Context context,
+                Lifecycle lifecycle) {
+            super(context, lifecycle);
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 3e90435..dad3a28 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -29,6 +29,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.robolectric.RuntimeEnvironment.application;
+import static org.robolectric.shadow.api.Shadow.extract;
 
 import android.app.ActivityManager;
 import android.content.ContentResolver;
@@ -66,7 +67,6 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
-import org.robolectric.internal.ShadowExtractor;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -79,7 +79,6 @@
         shadows = {TileUtilsTest.TileUtilsShadowRemoteViews.class})
 public class TileUtilsTest {
 
-    @Mock
     private Context mContext;
     @Mock
     private PackageManager mPackageManager;
@@ -97,6 +96,7 @@
 
     @Before
     public void setUp() throws NameNotFoundException {
+        mContext = spy(application);
         MockitoAnnotations.initMocks(this);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
@@ -456,8 +456,7 @@
         assertThat(tile.remoteViews).isNotNull();
         assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
         // Make sure the summary TextView got a new text string.
-        TileUtilsShadowRemoteViews shadowRemoteViews =
-                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
+        TileUtilsShadowRemoteViews shadowRemoteViews = extract(tile.remoteViews);
         assertThat(shadowRemoteViews.overrideViewId).isEqualTo(android.R.id.summary);
         assertThat(shadowRemoteViews.overrideText).isEqualTo("new summary text");
     }
@@ -494,8 +493,7 @@
         assertThat(tile.remoteViews).isNotNull();
         assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
         // Make sure the summary TextView didn't get any text view updates.
-        TileUtilsShadowRemoteViews shadowRemoteViews =
-                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
+        TileUtilsShadowRemoteViews shadowRemoteViews = extract(tile.remoteViews);
         assertThat(shadowRemoteViews.overrideViewId).isNull();
         assertThat(shadowRemoteViews.overrideText).isNull();
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
index f31d2e1..db599a7 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
@@ -18,8 +18,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.robolectric.RuntimeEnvironment.application;
+import static org.robolectric.shadow.api.Shadow.extract;
+
+import android.app.ApplicationPackageManager;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.ResolveInfo;
@@ -34,22 +37,21 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
-import org.robolectric.res.ResourceLoader;
-import org.robolectric.res.builder.DefaultPackageManager;
-import org.robolectric.res.builder.RobolectricPackageManager;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowApplicationPackageManager;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+        shadows = SuggestionParserTest.TestPackageManager.class)
 public class SuggestionParserTest {
 
-    private Context mContext;
-    private RobolectricPackageManager mPackageManager;
+    private TestPackageManager mPackageManager;
     private SuggestionParser mSuggestionParser;
     private SuggestionCategory mMultipleCategory;
     private SuggestionCategory mExclusiveCategory;
@@ -61,11 +63,8 @@
 
     @Before
     public void setUp() {
-        RuntimeEnvironment.setRobolectricPackageManager(
-                new TestPackageManager(RuntimeEnvironment.getAppResourceLoader()));
-        mContext = RuntimeEnvironment.application;
-        mPackageManager = RuntimeEnvironment.getRobolectricPackageManager();
-        mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+        mPackageManager = extract(application.getPackageManager());
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(application);
         mSuggestion = new Tile();
         mSuggestion.intent = new Intent("action");
         mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
@@ -81,7 +80,7 @@
         mExpiredExclusiveCategory.exclusive = true;
         mExpiredExclusiveCategory.exclusiveExpireDaysInMillis = 0;
 
-        mSuggestionParser = new SuggestionParser(mContext, mPrefs,
+        mSuggestionParser = new SuggestionParser(application, mPrefs,
                 Arrays.asList(mMultipleCategory, mExclusiveCategory, mExpiredExclusiveCategory),
                 "0");
 
@@ -199,7 +198,7 @@
 
         final Tile suggestion = mSuggestionsBeforeDismiss.get(0);
         if (mSuggestionParser.dismissSuggestion(suggestion)) {
-            RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent(
+            mPackageManager.removeResolveInfosForIntent(
                     new Intent(Intent.ACTION_MAIN).addCategory(mMultipleCategory.category),
                     suggestion.intent.getComponent().getPackageName());
         }
@@ -207,13 +206,10 @@
                 mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
     }
 
-    private static class TestPackageManager extends DefaultPackageManager {
+    @Implements(ApplicationPackageManager.class)
+    public static class TestPackageManager extends ShadowApplicationPackageManager {
 
-        TestPackageManager(ResourceLoader appResourceLoader) {
-            super(appResourceLoader);
-        }
-
-        @Override
+        @Implementation
         public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
             return super.queryIntentActivities(intent, flags);
         }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/SettingsLibShadowResources.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/SettingsLibShadowResources.java
index a376dcd..b53cc37 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/SettingsLibShadowResources.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/SettingsLibShadowResources.java
@@ -16,7 +16,7 @@
 
 package com.android.settingslib.testutils.shadow;
 
-import static org.robolectric.internal.Shadow.directlyOn;
+import static org.robolectric.shadow.api.Shadow.directlyOn;
 
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 87971cb..7b8d0db 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -273,6 +273,8 @@
             </intent-filter>
             <meta-data android:name="com.android.settings.category"
                     android:value="com.android.settings.category.ia.system" />
+            <meta-data android:name="com.android.settings.summary"
+                    android:resource="@string/summary_empty"/>
         </activity>
 
         <activity-alias android:name=".DemoMode"
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
index 1f633da..95ff13b 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
@@ -29,6 +29,9 @@
     default void showShutdownUi(boolean isReboot, String reason) {
     }
 
+    default void destroy() {
+    }
+
     @ProvidesInterface(version = GlobalActionsManager.VERSION)
     public interface GlobalActionsManager {
         int VERSION = 1;
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index b0f7d28..3dd0e6c 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -48,6 +48,9 @@
          to unlock the keyguard.  Displayed in one line in a large font.  -->
     <string name="keyguard_password_wrong_pin_code">Incorrect PIN code.</string>
 
+    <!-- Shown in the lock screen when there is SIM card IO error. -->
+    <string name="keyguard_sim_error_message_short">Invalid Card.</string>
+
     <!-- When the lock screen is showing, the phone is plugged in and the battery is fully
          charged, say that it is charged. -->
     <string name="keyguard_charged">Charged</string>
diff --git a/packages/SystemUI/res/drawable/recents_dismiss_all_history.xml b/packages/SystemUI/res/drawable/recents_dismiss_all_history.xml
deleted file mode 100644
index 6a417e6..0000000
--- a/packages/SystemUI/res/drawable/recents_dismiss_all_history.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<!--
-Copyright (C) 2016 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2 (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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="16dp"
-    android:width="28dp"
-    android:viewportHeight="48"
-    android:viewportWidth="72" >
-    <group
-        android:name="dismiss_all"
-        android:translateX="48"
-        android:translateY="6" >
-        <group
-            android:name="3"
-            android:translateX="-24"
-            android:translateY="36" >
-            <path
-                android:name="rectangle_path_1_2"
-                android:pathData="M -24.0,-6.0 l 48.0,0 l 0,12.0 l -48.0,0 Z"
-                android:fillColor="#FFFFFFFF"
-                android:fillAlpha="1" />
-        </group>
-        <group
-            android:name="2"
-            android:translateX="-12"
-            android:translateY="18" >
-            <path
-                android:name="rectangle_path_1_1"
-                android:pathData="M -24.0,-6.0 l 48.0,0 l 0,12.0 l -48.0,0 Z"
-                android:fillColor="#FFFFFFFF"
-                android:fillAlpha="1" />
-        </group>
-        <group
-            android:name="1" >
-            <path
-                android:name="rectangle_path_1"
-                android:pathData="M -24.0,-6.0 l 48.0,0 l 0,12.0 l -48.0,0 Z"
-                android:fillColor="#FFFFFFFF"
-                android:fillAlpha="1" />
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/layout/recents_task_view_header.xml b/packages/SystemUI/res/layout/recents_task_view_header.xml
index 5ee242d..1734506 100644
--- a/packages/SystemUI/res/layout/recents_task_view_header.xml
+++ b/packages/SystemUI/res/layout/recents_task_view_header.xml
@@ -66,14 +66,6 @@
         android:alpha="0"
         android:visibility="gone" />
 
-    <!-- The progress indicator shows if auto-paging is enabled -->
-    <ViewStub android:id="@+id/focus_timer_indicator_stub"
-               android:inflatedId="@+id/focus_timer_indicator"
-               android:layout="@layout/recents_task_view_header_progress_bar"
-               android:layout_width="match_parent"
-               android:layout_height="5dp"
-               android:layout_gravity="bottom" />
-
     <!-- The app overlay shows as the user long-presses on the app icon -->
     <ViewStub android:id="@+id/app_overlay_stub"
                android:inflatedId="@+id/app_overlay"
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index e561239..4bae85f 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -536,8 +536,8 @@
     <string name="activity_not_found" msgid="348423244327799974">"L\'aplicació no està instal·lada al dispositiu"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Mostra els segons del rellotge"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra els segons del rellotge a la barra d\'estat. Això pot afectar la durada de la bateria."</string>
-    <string name="qs_rearrange" msgid="8060918697551068765">"Reorganitza Configuració ràpida"</string>
-    <string name="show_brightness" msgid="6613930842805942519">"Mostra la brillantor a Configuració ràpida"</string>
+    <string name="qs_rearrange" msgid="8060918697551068765">"Reorganitza la configuració ràpida"</string>
+    <string name="show_brightness" msgid="6613930842805942519">"Mostra la brillantor a configuració ràpida"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vols activar el Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Per connectar el teclat amb la tauleta, primer has d\'activar el Bluetooth."</string>
@@ -705,7 +705,7 @@
     <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha afegit a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha suprimit"</string>
     <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha mogut a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string>
-    <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de la configuració ràpida."</string>
+    <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de configuració ràpida."</string>
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Notificació de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"És possible que l\'aplicació no funcioni amb la pantalla dividida."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'aplicació no admet la pantalla dividida."</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 8a1e0b9..0fe81d9 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -167,12 +167,6 @@
     <!-- The animation duration for scrolling the stack to a particular item. -->
     <integer name="recents_animate_task_stack_scroll_duration">200</integer>
 
-    <!-- The animation duration for scrolling the stack to a particular item. -->
-    <integer name="recents_auto_advance_duration">750</integer>
-
-    <!-- The animation duration for subsequent scrolling the stack to a particular item. -->
-    <integer name="recents_subsequent_auto_advance_duration">1000</integer>
-
     <!-- The delay to enforce between each alt-tab key press. -->
     <integer name="recents_alt_tab_key_delay">200</integer>
 
@@ -328,7 +322,7 @@
     <integer name="config_showTemperatureWarning">0</integer>
 
     <!-- Temp at which to show a warning notification if config_showTemperatureWarning is true.
-         If < 0, uses the value from
+         If < 0, uses the skin temperature sensor shutdown value from
          HardwarePropertiesManager#getDeviceTemperatures - config_warningTemperatureTolerance. -->
     <integer name="config_warningTemperature">-1</integer>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
index 159ac4c..13c48d0 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
@@ -39,6 +39,7 @@
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.settingslib.WirelessUtils;
+import android.telephony.TelephonyManager;
 
 public class CarrierText extends TextView {
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
@@ -52,6 +53,8 @@
 
     private WifiManager mWifiManager;
 
+    private boolean[] mSimErrorState = new boolean[TelephonyManager.getDefault().getPhoneCount()];
+
     private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
         @Override
         public void onRefreshCarrierInfo() {
@@ -65,6 +68,22 @@
         public void onStartedWakingUp() {
             setSelected(true);
         };
+
+        public void onSimStateChanged(int subId, int slotId, IccCardConstants.State simState) {
+            if (slotId < 0) {
+                Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId);
+                return;
+            }
+
+            if (DEBUG) Log.d(TAG,"onSimStateChanged: " + getStatusForIccState(simState));
+            if (getStatusForIccState(simState) == StatusMode.SimIoError) {
+                mSimErrorState[slotId] = true;
+                updateCarrierText();
+            } else if (mSimErrorState[slotId]) {
+                mSimErrorState[slotId] = false;
+                updateCarrierText();
+            }
+        };
     };
     /**
      * The status of this lock screen. Primarily used for widgets on LockScreen.
@@ -77,7 +96,8 @@
         SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
         SimLocked, // SIM card is currently locked
         SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
-        SimNotReady; // SIM is not ready yet. May never be on devices w/o a SIM.
+        SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM.
+        SimIoError; // SIM card is faulty
     }
 
     public CarrierText(Context context) {
@@ -101,6 +121,35 @@
         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
     }
 
+    /**
+     * Checks if there are faulty cards. Adds the text depending on the slot of the card
+     * @param text: current carrier text based on the sim state
+     * @param noSims: whether a valid sim card is inserted
+     * @return text
+    */
+    private CharSequence updateCarrierTextWithSimIoError(CharSequence text, boolean noSims) {
+        final CharSequence carrier = "";
+        CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
+            IccCardConstants.State.CARD_IO_ERROR, carrier);
+        for (int index = 0; index < mSimErrorState.length; index++) {
+            if (mSimErrorState[index]) {
+                // In the case when no sim cards are detected but a faulty card is inserted
+                // overwrite the text and only show "Invalid card"
+                if (noSims) {
+                    return concatenate(carrierTextForSimIOError,
+                        getContext().getText(com.android.internal.R.string.emergency_calls_only));
+                } else if (index == 0) {
+                    // prepend "Invalid card" when faulty card is inserted in slot 0
+                    text = concatenate(carrierTextForSimIOError, text);
+                } else {
+                    // concatenate "Invalid card" when faulty card is inserted in slot 1
+                    text = concatenate(text, carrierTextForSimIOError);
+                }
+            }
+        }
+        return text;
+    }
+
     protected void updateCarrierText() {
         boolean allSimsMissing = true;
         boolean anySimReadyAndInService = false;
@@ -179,6 +228,7 @@
             }
         }
 
+        displayText = updateCarrierTextWithSimIoError(displayText, allSimsMissing);
         // APM (airplane mode) != no carrier state. There are carrier services
         // (e.g. WFC = Wi-Fi calling) which may operate in APM.
         if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
@@ -270,6 +320,11 @@
                         getContext().getText(R.string.keyguard_sim_puk_locked_message),
                         text);
                 break;
+            case SimIoError:
+                carrierText = makeCarrierStringOnEmergencyCapable(
+                        getContext().getText(R.string.keyguard_sim_error_message_short),
+                        text);
+                break;
         }
 
         return carrierText;
@@ -319,6 +374,8 @@
                 return StatusMode.SimPermDisabled;
             case UNKNOWN:
                 return StatusMode.SimMissing;
+            case CARD_IO_ERROR:
+                return StatusMode.SimIoError;
         }
         return StatusMode.SimMissing;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
index 7baa57e..0cb6423 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -57,16 +57,16 @@
     SecurityMode getSecurityMode(int userId) {
         KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
 
-        if (SubscriptionManager.isValidSubscriptionId(
-                monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED))) {
-            return SecurityMode.SimPin;
-        }
-
         if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId(
                 monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED))) {
             return SecurityMode.SimPuk;
         }
 
+        if (SubscriptionManager.isValidSubscriptionId(
+                monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED))) {
+            return SecurityMode.SimPin;
+        }
+
         final int security = mLockPatternUtils.getActivePasswordQuality(userId);
         switch (security) {
             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index d83a6c6..2bb992c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -52,7 +52,6 @@
 import android.os.BatteryManager;
 import android.os.CancellationSignal;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.Message;
 import android.os.RemoteException;
@@ -78,7 +77,7 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.recents.misc.TaskStackChangeListener;
 
 import com.google.android.collect.Lists;
 
@@ -902,6 +901,8 @@
                 }
             } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
                 state = IccCardConstants.State.NETWORK_LOCKED;
+            } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
+                state = IccCardConstants.State.CARD_IO_ERROR;
             } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
                         || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
                 // This is required because telephony doesn't return to "READY" after
@@ -1771,7 +1772,7 @@
         }
     }
 
-    private final TaskStackListener mTaskStackListener = new TaskStackListener() {
+    private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
         @Override
         public void onTaskStackChangedBackground() {
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 4b37715..592dda0 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -83,7 +83,6 @@
 
     private boolean mMenuRowIntercepting;
     private boolean mLongPressSent;
-    private LongPressListener mLongPressListener;
     private Runnable mWatchLongPress;
     private final long mLongPressTimeout;
 
@@ -115,10 +114,6 @@
         mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f);
     }
 
-    public void setLongPressListener(LongPressListener listener) {
-        mLongPressListener = listener;
-    }
-
     public void setDensityScale(float densityScale) {
         mDensityScale = densityScale;
     }
@@ -257,7 +252,7 @@
         }
     }
 
-    public void removeLongPressCallback() {
+    public void cancelLongPress() {
         if (mWatchLongPress != null) {
             mHandler.removeCallbacks(mWatchLongPress);
             mWatchLongPress = null;
@@ -288,33 +283,27 @@
                     mInitialTouchPos = getPos(ev);
                     mPerpendicularInitialTouchPos = getPerpendicularPos(ev);
                     mTranslation = getTranslation(mCurrView);
-                    if (mLongPressListener != null) {
-                        if (mWatchLongPress == null) {
-                            mWatchLongPress = new Runnable() {
-                                @Override
-                                public void run() {
-                                    if (mCurrView != null && !mLongPressSent) {
-                                        mLongPressSent = true;
+                    if (mWatchLongPress == null) {
+                        mWatchLongPress = new Runnable() {
+                            @Override
+                            public void run() {
+                                if (mCurrView != null && !mLongPressSent) {
+                                    mLongPressSent = true;
+                                    mCurrView.getLocationOnScreen(mTmpPos);
+                                    final int x = (int) ev.getRawX() - mTmpPos[0];
+                                    final int y = (int) ev.getRawY() - mTmpPos[1];
+                                    if (mCurrView instanceof ExpandableNotificationRow) {
                                         mCurrView.sendAccessibilityEvent(
                                                 AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
-                                        mCurrView.getLocationOnScreen(mTmpPos);
-                                        final int x = (int) ev.getRawX() - mTmpPos[0];
-                                        final int y = (int) ev.getRawY() - mTmpPos[1];
-                                        MenuItem menuItem = null;
-                                        if (mCurrView instanceof ExpandableNotificationRow) {
-                                            menuItem = ((ExpandableNotificationRow) mCurrView)
-                                                    .getProvider().getLongpressMenuItem(mContext);
-                                        }
-                                        if (menuItem != null) {
-                                            mLongPressListener.onLongPress(mCurrView, x, y,
-                                                    menuItem);
-                                        }
+                                        ExpandableNotificationRow currRow =
+                                                (ExpandableNotificationRow) mCurrView;
+                                        currRow.doLongClickCallback(x, y);
                                     }
                                 }
-                            };
-                        }
-                        mHandler.postDelayed(mWatchLongPress, mLongPressTimeout);
+                            }
+                        };
                     }
+                    mHandler.postDelayed(mWatchLongPress, mLongPressTimeout);
                 }
                 break;
 
@@ -331,7 +320,7 @@
                         mDragging = true;
                         mInitialTouchPos = getPos(ev);
                         mTranslation = getTranslation(mCurrView);
-                        removeLongPressCallback();
+                        cancelLongPress();
                     }
                 }
                 break;
@@ -343,7 +332,7 @@
                 mCurrView = null;
                 mLongPressSent = false;
                 mMenuRowIntercepting = false;
-                removeLongPressCallback();
+                cancelLongPress();
                 if (captured) return true;
                 break;
         }
@@ -586,7 +575,7 @@
 
                 // We are not doing anything, make sure the long press callback
                 // is not still ticking like a bomb waiting to go off.
-                removeLongPressCallback();
+                cancelLongPress();
                 return false;
             }
         }
@@ -734,15 +723,4 @@
          */
         float getFalsingThresholdFactor();
     }
-
-    /**
-     * Equivalent to View.OnLongClickListener with coordinates
-     */
-    public interface LongPressListener {
-        /**
-         * Equivalent to {@link View.OnLongClickListener#onLongClick(View)} with coordinates
-         * @return whether the longpress was handled
-         */
-        boolean onLongPress(View v, int x, int y, MenuItem item);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index dc626fb..851b78c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -84,9 +84,6 @@
             case DOZE_REQUEST_PULSE:
                 pulseWhileDozing(mMachine.getPulseReason());
                 break;
-            case DOZE_PULSE_DONE:
-                mHost.abortPulsing();
-                break;
             case INITIALIZED:
                 mHost.startDozing();
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
index 09a08f0..f06cda0 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
@@ -31,6 +31,7 @@
 
 public class GlobalActionsComponent extends SystemUI implements Callbacks, GlobalActionsManager {
 
+    private GlobalActions mPlugin;
     private Extension<GlobalActions> mExtension;
     private IStatusBarService mBarService;
 
@@ -41,10 +42,19 @@
         mExtension = Dependency.get(ExtensionController.class).newExtension(GlobalActions.class)
                 .withPlugin(GlobalActions.class)
                 .withDefault(() -> new GlobalActionsImpl(mContext))
+                .withCallback(this::onExtensionCallback)
                 .build();
+        mPlugin = mExtension.get();
         SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
     }
 
+    private void onExtensionCallback(GlobalActions newPlugin) {
+        if (mPlugin != null) {
+            mPlugin.destroy();
+        }
+        mPlugin = newPlugin;
+    }
+
     @Override
     public void handleShowShutdownUi(boolean isReboot, String reason) {
         mExtension.get().showShutdownUi(isReboot, reason);
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 189badf..d82f9cd 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -16,27 +16,6 @@
 
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
 
-import com.android.internal.R;
-import com.android.internal.colorextraction.ColorExtractor;
-import com.android.internal.colorextraction.ColorExtractor.GradientColors;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.util.EmergencyAffordanceManager;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.Dependency;
-import com.android.systemui.HardwareUiLayout;
-import com.android.systemui.Interpolators;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
-import com.android.systemui.statusbar.notification.NotificationUtils;
-import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.systemui.volume.VolumeDialogMotion.LogAccelerateInterpolator;
-import com.android.systemui.volume.VolumeDialogMotion.LogDecelerateInterpolator;
-
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.ActivityManager;
 import android.app.Dialog;
 import android.app.WallpaperManager;
@@ -69,7 +48,6 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.MathUtils;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -86,7 +64,23 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.internal.R;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.colorextraction.drawable.GradientDrawable;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.util.EmergencyAffordanceManager;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.Dependency;
+import com.android.systemui.HardwareUiLayout;
+import com.android.systemui.Interpolators;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.volume.VolumeDialogMotion.LogAccelerateInterpolator;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -96,7 +90,8 @@
  * may show depending on whether the keyguard is showing, and whether the device
  * is provisioned.
  */
-class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
+class GlobalActionsDialog implements DialogInterface.OnDismissListener,
+        DialogInterface.OnClickListener {
 
     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
@@ -195,6 +190,14 @@
         }
     }
 
+    /**
+     * Dismiss the global actions dialog, if it's currently shown
+     */
+    public void dismissDialog() {
+        mHandler.removeMessages(MESSAGE_DISMISS);
+        mHandler.sendEmptyMessage(MESSAGE_DISMISS);
+    }
+
     private void awakenIfNecessary() {
         if (mDreamManager != null) {
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 2cf230c..3563437 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -14,12 +14,12 @@
 
 package com.android.systemui.globalactions;
 
+import static android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS;
+
 import android.app.Dialog;
 import android.app.KeyguardManager;
-import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.content.Context;
-import android.graphics.Color;
 import android.graphics.Point;
 import android.view.ViewGroup;
 import android.view.Window;
@@ -32,12 +32,14 @@
 import com.android.internal.colorextraction.drawable.GradientDrawable;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.GlobalActions;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
-public class GlobalActionsImpl implements GlobalActions {
+public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks {
 
     private static final float SHUTDOWN_SCRIM_ALPHA = 0.95f;
 
@@ -45,15 +47,23 @@
     private final KeyguardMonitor mKeyguardMonitor;
     private final DeviceProvisionedController mDeviceProvisionedController;
     private GlobalActionsDialog mGlobalActions;
+    private boolean mDisabled;
 
     public GlobalActionsImpl(Context context) {
         mContext = context;
         mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
+        SysUiServiceProvider.getComponent(context, CommandQueue.class).addCallbacks(this);
+    }
+
+    @Override
+    public void destroy() {
+        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
     }
 
     @Override
     public void showGlobalActions(GlobalActionsManager manager) {
+        if (mDisabled) return;
         if (mGlobalActions == null) {
             mGlobalActions = new GlobalActionsDialog(mContext, manager);
         }
@@ -107,4 +117,14 @@
 
         d.show();
     }
+
+    @Override
+    public void disable(int state1, int state2, boolean animate) {
+        final boolean disabled = (state2 & DISABLE2_GLOBAL_ACTIONS) != 0;
+        if (disabled == mDisabled) return;
+        mDisabled = disabled;
+        if (disabled && mGlobalActions != null) {
+            mGlobalActions.dismissDialog();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
index f198229..4c3d5ba 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.keyguard;
 
-import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.IActivityManager;
@@ -29,9 +28,8 @@
 import android.os.UserHandle;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.recents.misc.TaskStackChangeListener;
 
 public class WorkLockActivityController {
     private final Context mContext;
@@ -98,7 +96,7 @@
         }
     }
 
-    private final TaskStackListener mLockListener = new TaskStackListener() {
+    private final TaskStackChangeListener mLockListener = new TaskStackChangeListener() {
         @Override
         public void onTaskProfileLocked(int taskId, int userId) {
             startWorkChallengeInTask(taskId, userId);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index f8996aa..7e87666 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -41,8 +41,7 @@
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.component.ExpandPipEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
-import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.recents.misc.TaskStackChangeListener;
 
 import java.io.PrintWriter;
 
@@ -70,7 +69,7 @@
     /**
      * Handler for system task stack changes.
      */
-    TaskStackListener mTaskStackListener = new TaskStackListener() {
+    TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
         @Override
         public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
             mTouchHandler.onActivityPinned();
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index e0445c1..312b990 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -20,7 +20,6 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackInfo;
 import android.app.IActivityManager;
-import android.app.RemoteAction;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -47,7 +46,7 @@
 import com.android.systemui.R;
 import com.android.systemui.pip.BasePipManager;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.recents.misc.TaskStackChangeListener;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -621,7 +620,7 @@
         return false;
     }
 
-    private TaskStackListener mTaskStackListener = new TaskStackListener() {
+    private TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
         @Override
         public void onTaskStackChanged() {
             if (DEBUG) Log.d(TAG, "onTaskStackChanged()");
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index f378268..c1a3623 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -28,8 +28,14 @@
 import android.os.BatteryManager;
 import android.os.Handler;
 import android.os.HardwarePropertiesManager;
+import android.os.IBinder;
+import android.os.IThermalEventListener;
+import android.os.IThermalService;
 import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.Temperature;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.format.DateUtils;
@@ -75,6 +81,7 @@
     private float[] mRecentTemps = new float[MAX_RECENT_TEMPS];
     private int mNumTemps;
     private long mNextLogTime;
+    private IThermalService mThermalService;
 
     // We create a method reference here so that we are guaranteed that we can remove a callback
     // by using the same instance (method references are not guaranteed to be the same object
@@ -263,7 +270,7 @@
                 resources.getInteger(R.integer.config_warningTemperature));
 
         if (mThresholdTemp < 0f) {
-            // Get the throttling temperature. No need to check if we're not throttling.
+            // Get the shutdown temperature, adjust for warning tolerance.
             float[] throttlingTemps = mHardwarePropertiesManager.getDeviceTemperatures(
                     HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
                     HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
@@ -276,6 +283,25 @@
                     resources.getInteger(R.integer.config_warningTemperatureTolerance);
         }
 
+        if (mThermalService == null) {
+            // Enable push notifications of throttling from vendor thermal
+            // management subsystem via thermalservice, in addition to our
+            // usual polling, to react to temperature jumps more quickly.
+            IBinder b = ServiceManager.getService("thermalservice");
+
+            if (b != null) {
+                mThermalService = IThermalService.Stub.asInterface(b);
+                try {
+                    mThermalService.registerThermalEventListener(
+                        new ThermalEventListener());
+                } catch (RemoteException e) {
+                    // Should never happen.
+                }
+            } else {
+                Slog.w(TAG, "cannot find thermalservice, no throttling push notifications");
+            }
+        }
+
         setNextLogTime();
 
         // This initialization method may be called on a configuration change. Only one set of
@@ -414,5 +440,15 @@
         void dump(PrintWriter pw);
         void userSwitched();
     }
-}
 
+    // Thermal event received from vendor thermal management subsystem
+    private final class ThermalEventListener extends IThermalEventListener.Stub {
+        @Override public void notifyThrottling(boolean isThrottling, Temperature temp) {
+            // Trigger an update of the temperature warning.  Only one
+            // callback can be enabled at a time, so remove any existing
+            // callback; updateTemperatureWarning will schedule another one.
+            mHandler.removeCallbacks(mUpdateTempCallback);
+            updateTemperatureWarning();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 283ac0c..b96bd9b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -81,23 +81,15 @@
         implements RecentsComponent, CommandQueue.Callbacks {
 
     private final static String TAG = "Recents";
-    private final static boolean DEBUG = false;
 
     public final static int EVENT_BUS_PRIORITY = 1;
     public final static int BIND_TO_SYSTEM_USER_RETRY_DELAY = 5000;
-    public final static int RECENTS_GROW_TARGET_INVALID = -1;
 
     public final static Set<String> RECENTS_ACTIVITIES = new HashSet<>();
     static {
         RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY);
     }
 
-    // Purely for experimentation
-    private final static String RECENTS_OVERRIDE_SYSPROP_KEY = "persist.recents_override_pkg";
-    private final static String ACTION_SHOW_RECENTS = "com.android.systemui.recents.ACTION_SHOW";
-    private final static String ACTION_HIDE_RECENTS = "com.android.systemui.recents.ACTION_HIDE";
-    private final static String ACTION_TOGGLE_RECENTS = "com.android.systemui.recents.ACTION_TOGGLE";
-
     private static final String COUNTER_WINDOW_SUPPORTED = "window_enter_supported";
     private static final String COUNTER_WINDOW_UNSUPPORTED = "window_enter_unsupported";
     private static final String COUNTER_WINDOW_INCOMPATIBLE = "window_enter_incompatible";
@@ -107,11 +99,6 @@
     private static RecentsTaskLoader sTaskLoader;
     private static RecentsConfiguration sConfiguration;
 
-    // For experiments only, allows another package to handle recents if it is defined in the system
-    // properties.  This is limited to show/toggle/hide, and does not tie into the ActivityManager,
-    // and does not reside in the home stack.
-    private String mOverrideRecentsPackageName;
-
     private Handler mHandler;
     private RecentsImpl mImpl;
     private int mDraggingInRecentsCurrentUser;
@@ -204,21 +191,13 @@
 
     @Override
     public void start() {
-        sDebugFlags = new RecentsDebugFlags(mContext);
+        sDebugFlags = new RecentsDebugFlags();
         sSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
         sConfiguration = new RecentsConfiguration(mContext);
         sTaskLoader = new RecentsTaskLoader(mContext);
         mHandler = new Handler();
         mImpl = new RecentsImpl(mContext);
 
-        // Check if there is a recents override package
-        if (Build.IS_USERDEBUG || Build.IS_ENG) {
-            String cnStr = SystemProperties.get(RECENTS_OVERRIDE_SYSPROP_KEY);
-            if (!cnStr.isEmpty()) {
-                mOverrideRecentsPackageName = cnStr;
-            }
-        }
-
         // Register with the event bus
         EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
         EventBus.getDefault().register(sSystemServicesProxy, EVENT_BUS_PRIORITY);
@@ -257,16 +236,8 @@
             return;
         }
 
-        if (proxyToOverridePackage(ACTION_SHOW_RECENTS)) {
-            return;
-        }
-        try {
-            ActivityManager.getService().closeSystemDialogs(SYSTEM_DIALOG_REASON_RECENT_APPS);
-        } catch (RemoteException e) {
-        }
-
+        sSystemServicesProxy.sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
         int recentsGrowTarget = getComponent(Divider.class).getView().growsRecents();
-
         int currentUser = sSystemServicesProxy.getCurrentUser();
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
@@ -301,10 +272,6 @@
             return;
         }
 
-        if (proxyToOverridePackage(ACTION_HIDE_RECENTS)) {
-            return;
-        }
-
         int currentUser = sSystemServicesProxy.getCurrentUser();
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
@@ -336,12 +303,7 @@
             return;
         }
 
-        if (proxyToOverridePackage(ACTION_TOGGLE_RECENTS)) {
-            return;
-        }
-
         int growTarget = getComponent(Divider.class).getView().growsRecents();
-
         int currentUser = sSystemServicesProxy.getCurrentUser();
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.toggleRecents(growTarget);
@@ -820,21 +782,6 @@
                 (Settings.Secure.getInt(cr, Settings.Secure.USER_SETUP_COMPLETE, 0) != 0);
     }
 
-    /**
-     * Attempts to proxy the following action to the override recents package.
-     * @return whether the proxying was successful
-     */
-    private boolean proxyToOverridePackage(String action) {
-        if (mOverrideRecentsPackageName != null) {
-            Intent intent = new Intent(action);
-            intent.setPackage(mOverrideRecentsPackageName);
-            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-            mContext.sendBroadcast(intent);
-            return true;
-        }
-        return false;
-    }
-
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("Recents");
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 86b7790..711885c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -17,7 +17,6 @@
 package com.android.systemui.recents;
 
 import android.app.Activity;
-import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.TaskStackBuilder;
 import android.app.WallpaperManager;
@@ -29,10 +28,10 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.provider.Settings.Secure;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
@@ -42,6 +41,7 @@
 import android.view.WindowManager.LayoutParams;
 
 import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.content.PackageMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.LatencyTracker;
@@ -53,7 +53,6 @@
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
-import com.android.systemui.recents.events.activity.DebugFlagsChangedEvent;
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
 import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
@@ -61,10 +60,10 @@
 import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
-import com.android.systemui.recents.events.activity.IterateRecentsEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
 import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
+import com.android.systemui.recents.events.activity.PackagesChangedEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
 import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
 import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
@@ -79,17 +78,14 @@
 import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
 import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
 import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
-import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
 import com.android.systemui.recents.events.ui.UserInteractionEvent;
 import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent.Direction;
-import com.android.systemui.recents.misc.DozeTrigger;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
-import com.android.systemui.recents.model.RecentsPackageMonitor;
 import com.android.systemui.recents.model.RecentsTaskLoadPlan;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
@@ -100,7 +96,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.List;
 
 /**
  * The main Recents activity that is started from RecentsComponent.
@@ -114,7 +109,23 @@
     public final static int EVENT_BUS_PRIORITY = Recents.EVENT_BUS_PRIORITY + 1;
     public final static int INCOMPATIBLE_APP_ALPHA_DURATION = 150;
 
-    private RecentsPackageMonitor mPackageMonitor;
+    private PackageMonitor mPackageMonitor = new PackageMonitor() {
+            @Override
+            public void onPackageRemoved(String packageName, int uid) {
+                RecentsActivity.this.onPackageChanged(packageName, getChangingUserId());
+            }
+
+            @Override
+            public boolean onPackageChanged(String packageName, int uid, String[] components) {
+                RecentsActivity.this.onPackageChanged(packageName, getChangingUserId());
+                return true;
+            }
+
+            @Override
+            public void onPackageModified(String packageName) {
+                RecentsActivity.this.onPackageChanged(packageName, getChangingUserId());
+            }
+        };
     private Handler mHandler = new Handler();
     private long mLastTabKeyEventTime;
     private boolean mFinishedOnStartup;
@@ -133,7 +144,6 @@
 
     // The trigger to automatically launch the current task
     private int mFocusTimerDuration;
-    private DozeTrigger mIterateTrigger;
     private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
 
     // Theme and colors
@@ -188,41 +198,6 @@
             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                 // When switching users, dismiss Recents to Home similar to screen off
                 finish();
-            } else if (action.equals(Intent.ACTION_TIME_CHANGED)) {
-                // If the time shifts but the currentTime >= lastStackActiveTime, then that boundary
-                // is still valid.  Otherwise, we need to reset the lastStackactiveTime to the
-                // currentTime and remove the old tasks in between which would not be previously
-                // visible, but currently would be in the new currentTime
-                int currentUser = SystemServicesProxy.getInstance(RecentsActivity.this)
-                        .getCurrentUser();
-                long oldLastStackActiveTime = Settings.Secure.getLongForUser(getContentResolver(),
-                        Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, -1, currentUser);
-                if (oldLastStackActiveTime != -1) {
-                    long currentTime = System.currentTimeMillis();
-                    if (currentTime < oldLastStackActiveTime) {
-                        // We are only removing tasks that are between the new current time
-                        // and the old last stack active time, they were not visible and in the
-                        // TaskStack so we don't need to remove any associated TaskViews but we do
-                        // need to load the task id's from the system
-                        RecentsTaskLoader loader = Recents.getTaskLoader();
-                        RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(ctx);
-                        loader.preloadRawTasks(loadPlan, false /* includeFrontMostExcludedTask */);
-                        List<ActivityManager.RecentTaskInfo> tasks = loadPlan.getRawTasks();
-                        for (int i = tasks.size() - 1; i >= 0; i--) {
-                            ActivityManager.RecentTaskInfo task = tasks.get(i);
-                            if (currentTime <= task.lastActiveTime && task.lastActiveTime <
-                                    oldLastStackActiveTime) {
-                                Recents.getSystemServices().removeTask(task.persistentId);
-                            }
-                        }
-                        Recents.getSystemServices().updateOverviewLastStackActiveTimeAsync(
-                                currentTime, currentUser);
-
-                        // Clear the last PiP task time, it's an edge case and we'd rather it
-                        // not relaunch the PiP task if the user double taps
-                        RecentsImpl.clearLastPipTime();
-                    }
-                }
             }
         }
     };
@@ -340,8 +315,8 @@
         EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
 
         // Initialize the package monitor
-        mPackageMonitor = new RecentsPackageMonitor();
-        mPackageMonitor.register(this);
+        mPackageMonitor.register(this, Looper.getMainLooper(), UserHandle.ALL,
+                true /* externalStorage */);
 
         // Select theme based on wallpaper colors
         mColorExtractor = Dependency.get(SysuiColorExtractor.class);
@@ -363,13 +338,6 @@
         }
 
         mLastConfig = new Configuration(Utilities.getAppConfiguration(this));
-        mFocusTimerDuration = getResources().getInteger(R.integer.recents_auto_advance_duration);
-        mIterateTrigger = new DozeTrigger(mFocusTimerDuration, new Runnable() {
-            @Override
-            public void run() {
-                dismissRecentsToFocusedTask(MetricsEvent.OVERVIEW_SELECT_TIMEOUT);
-            }
-        });
 
         // Set the window background
         mRecentsView.updateBackgroundScrim(getWindow(), isInMultiWindowMode());
@@ -383,7 +351,6 @@
         // Register the broadcast receiver to handle messages when the screen is turned off
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
-        filter.addAction(Intent.ACTION_TIME_CHANGED);
         filter.addAction(Intent.ACTION_USER_SWITCHED);
         registerReceiver(mSystemBroadcastReceiver, filter);
 
@@ -467,8 +434,7 @@
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
         if (!loadPlan.hasTasks()) {
-            loader.preloadTasks(loadPlan, launchState.launchedToTaskId,
-                    !launchState.launchedFromHome && !launchState.launchedViaDockGesture);
+            loader.preloadTasks(loadPlan, launchState.launchedToTaskId);
         }
 
         RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
@@ -540,7 +506,6 @@
         super.onPause();
 
         mIgnoreAltTabRelease = false;
-        mIterateTrigger.stopDozing();
     }
 
     @Override
@@ -643,8 +608,7 @@
                     if (backward) {
                         EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
                     } else {
-                        EventBus.getDefault().send(
-                                new FocusNextTaskViewEvent(0 /* timerIndicatorDuration */));
+                        EventBus.getDefault().send(new FocusNextTaskViewEvent());
                     }
                     mLastTabKeyEventTime = SystemClock.elapsedRealtime();
 
@@ -702,38 +666,10 @@
         }
     }
 
-    public final void onBusEvent(IterateRecentsEvent event) {
-        final RecentsDebugFlags debugFlags = Recents.getDebugFlags();
-
-        // Start dozing after the recents button is clicked
-        int timerIndicatorDuration = 0;
-        if (debugFlags.isFastToggleRecentsEnabled()) {
-            timerIndicatorDuration = getResources().getInteger(
-                    R.integer.recents_subsequent_auto_advance_duration);
-
-            mIterateTrigger.setDozeDuration(timerIndicatorDuration);
-            if (!mIterateTrigger.isDozing()) {
-                mIterateTrigger.startDozing();
-            } else {
-                mIterateTrigger.poke();
-            }
-        }
-
-        // Focus the next task
-        EventBus.getDefault().send(new FocusNextTaskViewEvent(timerIndicatorDuration));
-
-        MetricsLogger.action(this, MetricsEvent.ACTION_OVERVIEW_PAGE);
-    }
-
     public final void onBusEvent(RecentsActivityStartingEvent event) {
         mRecentsStartRequested = true;
     }
 
-    public final void onBusEvent(UserInteractionEvent event) {
-        // Stop the fast-toggle dozer
-        mIterateTrigger.stopDozing();
-    }
-
     public final void onBusEvent(HideRecentsEvent event) {
         if (event.triggeredFromAltTab) {
             // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
@@ -751,15 +687,11 @@
     }
 
     public final void onBusEvent(EnterRecentsWindowLastAnimationFrameEvent event) {
-        EventBus.getDefault().send(new UpdateFreeformTaskViewVisibilityEvent(true));
         mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
         mRecentsView.invalidate();
     }
 
     public final void onBusEvent(ExitRecentsWindowFirstAnimationFrameEvent event) {
-        if (mRecentsView.isLastTaskLaunchedFreeform()) {
-            EventBus.getDefault().send(new UpdateFreeformTaskViewVisibilityEvent(false));
-        }
         mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
         mRecentsView.invalidate();
     }
@@ -859,11 +791,6 @@
         MetricsLogger.count(this, "overview_screen_pinned", 1);
     }
 
-    public final void onBusEvent(DebugFlagsChangedEvent event) {
-        // Just finish recents so that we can reload the flags anew on the next instantiation
-        finish();
-    }
-
     public final void onBusEvent(StackViewScrolledEvent event) {
         // Once the user has scrolled while holding alt-tab, then we should ignore the release of
         // the key
@@ -889,8 +816,7 @@
         RecentsActivityLaunchState launchState = config.getLaunchState();
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
-        loader.preloadTasks(loadPlan, -1 /* runningTaskId */,
-                false /* includeFrontMostExcludedTask */);
+        loader.preloadTasks(loadPlan, -1 /* runningTaskId */);
 
         RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
         loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
@@ -924,6 +850,11 @@
         return true;
     }
 
+    public void onPackageChanged(String packageName, int userId) {
+        Recents.getTaskLoader().onPackageChanged(packageName);
+        EventBus.getDefault().send(new PackagesChangedEvent(packageName, userId));
+    }
+
     @Override
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
         super.dump(prefix, fd, writer, args);
@@ -931,13 +862,9 @@
         Recents.getTaskLoader().dump(prefix, writer);
 
         String id = Integer.toHexString(System.identityHashCode(this));
-        long lastStackActiveTime = Settings.Secure.getLongForUser(getContentResolver(),
-                Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, -1,
-                SystemServicesProxy.getInstance(this).getCurrentUser());
 
         writer.print(prefix); writer.print(TAG);
         writer.print(" visible="); writer.print(mIsVisible ? "Y" : "N");
-        writer.print(" lastStackTaskActiveTime="); writer.print(lastStackActiveTime);
         writer.print(" currentTime="); writer.print(System.currentTimeMillis());
         writer.print(" [0x"); writer.print(id); writer.print("]");
         writer.println();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
index 5b8ed94..2c3a727 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -60,12 +60,6 @@
         RecentsDebugFlags debugFlags = Recents.getDebugFlags();
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
         if (launchedFromApp) {
-            if (!launchState.launchedWithAltTab && debugFlags.isFastToggleRecentsEnabled()) {
-                // If fast toggling, focus the front most task so that the next tap will launch the
-                // task
-                return numTasks - 1;
-            }
-
             if (launchState.launchedFromBlacklistedApp) {
                 // If we are launching from a blacklisted app, focus the front most task so that the
                 // next tap will launch the task
@@ -80,12 +74,6 @@
             // If coming from another app, focus the next task
             return Math.max(0, numTasks - 2);
         } else {
-            if (!launchState.launchedWithAltTab && debugFlags.isFastToggleRecentsEnabled()) {
-                // If fast toggling, defer focusing until the next tap (which will automatically
-                // focus the front most task)
-                return -1;
-            }
-
             // If coming from home, focus the front most task
             return numTasks - 1;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
index 0262a09..a8dafbf 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
@@ -16,75 +16,16 @@
 
 package com.android.systemui.recents;
 
-import android.content.Context;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.DebugFlagsChangedEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.tuner.TunerService;
-
-/**
- * Tunable debug flags
- */
-public class RecentsDebugFlags implements TunerService.Tunable {
+public class RecentsDebugFlags {
 
     public static class Static {
         // Enables debug drawing for the transition thumbnail
         public static final boolean EnableTransitionThumbnailDebugMode = false;
-        // This disables the bitmap and icon caches
-        public static final boolean DisableBackgroundCache = false;
-        // Enables the task affiliations
-        public static final boolean EnableAffiliatedTaskGroups = false;
-        // Enables the button above the stack
-        public static final boolean EnableStackActionButton = true;
-        // Overrides the Tuner flags and enables the timeout
-        private static final boolean EnableFastToggleTimeout = false;
-        // Overrides the Tuner flags and enables the paging via the Recents button
-        private static final boolean EnablePaging = false;
+        // Enables debug thumbnail to be fetched
+        public static final boolean EnableThumbnailDebugMode = false;
+
         // Disables enter and exit transitions for other tasks for low ram devices
         public static final boolean DisableRecentsLowRamEnterExitAnimation = false;
 
-        // Enables us to create mock recents tasks
-        public static final boolean EnableMockTasks = false;
-        // Defines the number of mock recents packages to create
-        public static final int MockTasksPackageCount = 3;
-        // Defines the number of mock recents tasks to create
-        public static final int MockTaskCount = 100;
-        // Enables the simulated task affiliations
-        public static final boolean EnableMockTaskGroups = false;
-        // Defines the number of mock task affiliations per group
-        public static final int MockTaskGroupsTaskCount = 12;
-    }
-
-    /**
-     * We read the prefs once when we start the activity, then update them as the tuner changes
-     * the flags.
-     */
-    public RecentsDebugFlags(Context context) {
-        // Register all our flags, this will also call onTuningChanged() for each key, which will
-        // initialize the current state of each flag
-    }
-
-    /**
-     * @return whether we are enabling fast toggling.
-     */
-    public boolean isFastToggleRecentsEnabled() {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.hasFreeformWorkspaceSupport() || ssp.isTouchExplorationEnabled()) {
-            return false;
-        }
-        return Static.EnableFastToggleTimeout;
-    }
-
-    /**
-     * @return whether we are enabling paging.
-     */
-    public boolean isPagingEnabled() {
-        return Static.EnablePaging;
-    }
-
-    @Override
-    public void onTuningChanged(String key, String newValue) {
-        EventBus.getDefault().send(new DebugFlagsChangedEvent());
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 3e2a5f3..3f8d53f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -18,7 +18,6 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.view.View.MeasureSpec;
 
 import android.app.ActivityManager;
@@ -56,7 +55,6 @@
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
-import com.android.systemui.recents.events.activity.IterateRecentsEvent;
 import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestEvent;
 import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
@@ -72,12 +70,11 @@
 import com.android.systemui.recents.misc.DozeTrigger;
 import com.android.systemui.recents.misc.ForegroundThread;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.recents.misc.TaskStackChangeListener;
 import com.android.systemui.recents.model.RecentsTaskLoadPlan;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.Task.TaskKey;
-import com.android.systemui.recents.model.TaskGrouping;
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.model.ThumbnailData;
 import com.android.systemui.recents.views.RecentsTransitionHelper;
@@ -85,7 +82,6 @@
 import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
 import com.android.systemui.recents.views.TaskStackLayoutAlgorithm.VisibilityReport;
 import com.android.systemui.recents.views.TaskStackView;
-import com.android.systemui.recents.views.TaskStackViewScroller;
 import com.android.systemui.recents.views.TaskViewHeader;
 import com.android.systemui.recents.views.TaskViewTransform;
 import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
@@ -117,10 +113,10 @@
     public final static String RECENTS_ACTIVITY = "com.android.systemui.recents.RecentsActivity";
 
     /**
-     * An implementation of TaskStackListener, that allows us to listen for changes to the system
+     * An implementation of TaskStackChangeListener, that allows us to listen for changes to the system
      * task stacks and update recents accordingly.
      */
-    class TaskStackListenerImpl extends TaskStackListener {
+    class TaskStackListenerImpl extends TaskStackChangeListener {
 
         @Override
         public void onTaskStackChangedBackground() {
@@ -142,7 +138,7 @@
                 ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask();
                 RecentsTaskLoader loader = Recents.getTaskLoader();
                 RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-                loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */);
+                loader.preloadTasks(plan, -1);
                 TaskStack stack = plan.getTaskStack();
                 RecentsActivityLaunchState launchState = new RecentsActivityLaunchState();
                 RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
@@ -283,7 +279,7 @@
         // We can use a new plan since the caches will be the same.
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-        loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */);
+        loader.preloadTasks(plan, -1);
         RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
         launchOpts.numVisibleTasks = loader.getIconCacheSize();
         launchOpts.numVisibleTaskThumbnails = loader.getThumbnailCacheSize();
@@ -409,22 +405,17 @@
                 RecentsConfiguration config = Recents.getConfiguration();
                 RecentsActivityLaunchState launchState = config.getLaunchState();
                 if (!launchState.launchedWithAltTab) {
-                    // Has the user tapped quickly?
-                    boolean isQuickTap = elapsedTime < ViewConfiguration.getDoubleTapTimeout();
                     if (Recents.getConfiguration().isGridEnabled) {
+                        // Has the user tapped quickly?
+                        boolean isQuickTap = elapsedTime < ViewConfiguration.getDoubleTapTimeout();
                         if (isQuickTap) {
                             EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
                         } else {
                             EventBus.getDefault().post(new LaunchMostRecentTaskRequestEvent());
                         }
                     } else {
-                        if (!debugFlags.isPagingEnabled() || isQuickTap) {
-                            // Launch the next focused task
-                            EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
-                        } else {
-                            // Notify recents to move onto the next task
-                            EventBus.getDefault().post(new IterateRecentsEvent());
-                        }
+                        // Launch the next focused task
+                        EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
                     }
                 } else {
                     // If the user has toggled it too quickly, then just eat up the event here (it's
@@ -473,8 +464,7 @@
         // RecentsActivity) only if there is a task to animate to.  Post this to ensure that we
         // don't block the touch feedback on the nav bar button which triggers this.
         mHandler.post(() -> {
-            MutableBoolean isHomeStackVisible = new MutableBoolean(true);
-            if (!ssp.isRecentsActivityVisible(isHomeStackVisible)) {
+            if (!ssp.isRecentsActivityVisible(null)) {
                 ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
                 if (runningTask == null) {
                     return;
@@ -482,7 +472,7 @@
 
                 RecentsTaskLoader loader = Recents.getTaskLoader();
                 sInstanceLoadPlan = loader.createLoadPlan(mContext);
-                loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible.value);
+                loader.preloadTasks(sInstanceLoadPlan, runningTask.id);
                 TaskStack stack = sInstanceLoadPlan.getTaskStack();
                 if (stack.getTaskCount() > 0) {
                     // Only preload the icon (but not the thumbnail since it may not have been taken
@@ -522,7 +512,7 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-        loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */);
+        loader.preloadTasks(plan, -1);
         TaskStack focusedStack = plan.getTaskStack();
 
         // Return early if there are no tasks in the focused stack
@@ -577,7 +567,7 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-        loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */);
+        loader.preloadTasks(plan, -1);
         TaskStack focusedStack = plan.getTaskStack();
 
         // Return early if there are no tasks in the focused stack
@@ -595,43 +585,38 @@
         Task toTask = null;
         ActivityOptions launchOpts = null;
         int taskCount = tasks.size();
-        int numAffiliatedTasks = 0;
         for (int i = 0; i < taskCount; i++) {
             Task task = tasks.get(i);
             if (task.key.id == runningTask.id) {
-                TaskGrouping group = task.group;
-                Task.TaskKey toTaskKey;
                 if (showNextTask) {
-                    toTaskKey = group.getNextTaskInGroup(task);
-                    launchOpts = ActivityOptions.makeCustomAnimation(mContext,
-                            R.anim.recents_launch_next_affiliated_task_target,
-                            R.anim.recents_launch_next_affiliated_task_source);
+                    if ((i + 1) < taskCount) {
+                        toTask = tasks.get(i + 1);
+                        launchOpts = ActivityOptions.makeCustomAnimation(mContext,
+                                R.anim.recents_launch_next_affiliated_task_target,
+                                R.anim.recents_launch_next_affiliated_task_source);
+                    }
                 } else {
-                    toTaskKey = group.getPrevTaskInGroup(task);
-                    launchOpts = ActivityOptions.makeCustomAnimation(mContext,
-                            R.anim.recents_launch_prev_affiliated_task_target,
-                            R.anim.recents_launch_prev_affiliated_task_source);
+                    if ((i - 1) >= 0) {
+                        toTask = tasks.get(i - 1);
+                        launchOpts = ActivityOptions.makeCustomAnimation(mContext,
+                                R.anim.recents_launch_prev_affiliated_task_target,
+                                R.anim.recents_launch_prev_affiliated_task_source);
+                    }
                 }
-                if (toTaskKey != null) {
-                    toTask = focusedStack.findTaskWithId(toTaskKey.id);
-                }
-                numAffiliatedTasks = group.getTaskCount();
                 break;
             }
         }
 
         // Return early if there is no next task
         if (toTask == null) {
-            if (numAffiliatedTasks > 1) {
-                if (showNextTask) {
-                    ssp.startInPlaceAnimationOnFrontMostApplication(
-                            ActivityOptions.makeCustomInPlaceAnimation(mContext,
-                                    R.anim.recents_launch_next_affiliated_task_bounce));
-                } else {
-                    ssp.startInPlaceAnimationOnFrontMostApplication(
-                            ActivityOptions.makeCustomInPlaceAnimation(mContext,
-                                    R.anim.recents_launch_prev_affiliated_task_bounce));
-                }
+            if (showNextTask) {
+                ssp.startInPlaceAnimationOnFrontMostApplication(
+                        ActivityOptions.makeCustomInPlaceAnimation(mContext,
+                                R.anim.recents_launch_next_affiliated_task_bounce));
+            } else {
+                ssp.startInPlaceAnimationOnFrontMostApplication(
+                        ActivityOptions.makeCustomInPlaceAnimation(mContext,
+                                R.anim.recents_launch_prev_affiliated_task_bounce));
             }
             return;
         }
@@ -753,8 +738,7 @@
             stackLayout.getTaskStackBounds(displayRect, windowRect, systemInsets.top,
                     systemInsets.left, systemInsets.right, mTmpBounds);
             stackLayout.reset();
-            stackLayout.initialize(displayRect, windowRect, mTmpBounds,
-                    TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
+            stackLayout.initialize(displayRect, windowRect, mTmpBounds);
         }
     }
 
@@ -873,61 +857,29 @@
             getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo runningTask,
                     Rect windowOverrideRect) {
         final boolean isLowRamDevice = Recents.getConfiguration().isLowRamDevice;
-        if (runningTask != null
-                && runningTask.configuration.windowConfiguration.getWindowingMode()
-                == WINDOWING_MODE_FREEFORM) {
-            ArrayList<AppTransitionAnimationSpec> specs = new ArrayList<>();
-            ArrayList<Task> tasks = mDummyStackView.getStack().getStackTasks();
-            TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
-            TaskStackViewScroller stackScroller = mDummyStackView.getScroller();
 
-            mDummyStackView.updateLayoutAlgorithm(true /* boundScroll */);
-            mDummyStackView.updateToInitialState();
+        // Update the destination rect
+        Task toTask = new Task();
+        TaskViewTransform toTransform = getThumbnailTransitionTransform(mDummyStackView, toTask,
+                windowOverrideRect);
 
-            for (int i = tasks.size() - 1; i >= 0; i--) {
-                Task task = tasks.get(i);
-                if (task.isFreeformTask()) {
-                    mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task,
-                            stackScroller.getStackScroll(), mTmpTransform, null,
-                            windowOverrideRect);
-                    GraphicBuffer thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform);
-                    Rect toTaskRect = new Rect();
-                    mTmpTransform.rect.round(toTaskRect);
-                    specs.add(new AppTransitionAnimationSpec(task.key.id, thumbnail, toTaskRect));
-                }
-            }
-            AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()];
-            specs.toArray(specsArray);
+        RectF toTaskRect = toTransform.rect;
+        AppTransitionAnimationSpecsFuture future =
+                new RecentsTransitionHelper(mContext).getAppTransitionFuture(
+                        () -> {
+                    Rect rect = new Rect();
+                    toTaskRect.round(rect);
+                    GraphicBuffer thumbnail = drawThumbnailTransitionBitmap(toTask,
+                            toTransform);
+                    return Lists.newArrayList(new AppTransitionAnimationSpec(
+                            toTask.key.id, thumbnail, rect));
+                });
 
-            // For low end ram devices, wait for transition flag is reset when Recents entrance
-            // animation is complete instead of when the transition animation starts
-            return new Pair<>(ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
-                    specsArray, mHandler, isLowRamDevice ? null : mResetToggleFlagListener, this),
-                    null);
-        } else {
-            // Update the destination rect
-            Task toTask = new Task();
-            TaskViewTransform toTransform = getThumbnailTransitionTransform(mDummyStackView, toTask,
-                    windowOverrideRect);
-
-            RectF toTaskRect = toTransform.rect;
-            AppTransitionAnimationSpecsFuture future =
-                    new RecentsTransitionHelper(mContext).getAppTransitionFuture(
-                            () -> {
-                        Rect rect = new Rect();
-                        toTaskRect.round(rect);
-                        GraphicBuffer thumbnail = drawThumbnailTransitionBitmap(toTask,
-                                toTransform);
-                        return Lists.newArrayList(new AppTransitionAnimationSpec(
-                                toTask.key.id, thumbnail, rect));
-                    });
-
-            // For low end ram devices, wait for transition flag is reset when Recents entrance
-            // animation is complete instead of when the transition animation starts
-            return new Pair<>(ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
-                    mHandler, future.getFuture(), isLowRamDevice ? null : mResetToggleFlagListener,
-                    false /* scaleUp */), future);
-        }
+        // For low end ram devices, wait for transition flag is reset when Recents entrance
+        // animation is complete instead of when the transition animation starts
+        return new Pair<>(ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
+                mHandler, future.getFuture(), isLowRamDevice ? null : mResetToggleFlagListener,
+                false /* scaleUp */), future);
     }
 
     /**
@@ -942,7 +894,7 @@
             runningTaskOut.copyFrom(launchTask);
         } else {
             // If no task is specified or we can not find the task just use the front most one
-            launchTask = stack.getStackFrontMostTask(true /* includeFreeform */);
+            launchTask = stack.getStackFrontMostTask();
             runningTaskOut.copyFrom(launchTask);
         }
 
@@ -1012,7 +964,7 @@
             sInstanceLoadPlan = loader.createLoadPlan(mContext);
         }
         if (mLaunchedWhileDocking || mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
-            loader.preloadTasks(sInstanceLoadPlan, runningTaskId, !isHomeStackVisible);
+            loader.preloadTasks(sInstanceLoadPlan, runningTaskId);
         }
 
         TaskStack stack = sInstanceLoadPlan.getTaskStack();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/IterateRecentsEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/IterateRecentsEvent.java
deleted file mode 100644
index f7b2706..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/IterateRecentsEvent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the user taps on the Overview button to iterate to the next item in the
- * Recents list.
- */
-public class IterateRecentsEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/PackagesChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/PackagesChangedEvent.java
index 3b68574..47670e0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/PackagesChangedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/PackagesChangedEvent.java
@@ -17,22 +17,20 @@
 package com.android.systemui.recents.events.activity;
 
 import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.model.RecentsPackageMonitor;
 import com.android.systemui.recents.views.TaskStackView;
+import com.android.systemui.recents.RecentsActivity;
 
 /**
- * This event is sent by {@link RecentsPackageMonitor} when a package on the the system changes.
+ * This event is sent by {@link RecentsActivity} when a package on the the system changes.
  * {@link TaskStackView}s listen for this event, and remove the tasks associated with the removed
  * packages.
  */
 public class PackagesChangedEvent extends EventBus.Event {
 
-    public final RecentsPackageMonitor monitor;
     public final String packageName;
     public final int userId;
 
-    public PackagesChangedEvent(RecentsPackageMonitor monitor, String packageName, int userId) {
-        this.monitor = monitor;
+    public PackagesChangedEvent(String packageName, int userId) {
         this.packageName = packageName;
         this.userId = userId;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/UpdateFreeformTaskViewVisibilityEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/UpdateFreeformTaskViewVisibilityEvent.java
deleted file mode 100644
index b42da9c..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/UpdateFreeformTaskViewVisibilityEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent to update the visibility of all visible freeform task views.
- */
-public class UpdateFreeformTaskViewVisibilityEvent extends EventBus.Event {
-
-    public final boolean visible;
-
-    public UpdateFreeformTaskViewVisibilityEvent(boolean visible) {
-        this.visible = visible;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
index a1e4957..171ab5e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
@@ -22,10 +22,5 @@
  * Focuses the next task view in the stack.
  */
 public class FocusNextTaskViewEvent extends EventBus.Event {
-
-    public final int timerIndicatorDuration;
-
-    public FocusNextTaskViewEvent(int timerIndicatorDuration) {
-        this.timerIndicatorDuration = timerIndicatorDuration;
-    }
+    // Simple event
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/NamedCounter.java b/packages/SystemUI/src/com/android/systemui/recents/misc/NamedCounter.java
deleted file mode 100644
index ec3c39c..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/NamedCounter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.misc;
-
-/**
- * Used to generate successive incremented names.
- */
-public class NamedCounter {
-
-    int mCount;
-    String mPrefix = "";
-    String mSuffix = "";
-
-    public NamedCounter(String prefix, String suffix) {
-        mPrefix = prefix;
-        mSuffix = suffix;
-    }
-
-    /** Returns the next name. */
-    public String nextName() {
-        String name = mPrefix + mCount + mSuffix;
-        mCount++;
-        return name;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index bddf9a5..a392eff 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.recents.misc;
 
+import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -25,13 +26,11 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackInfo;
-import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
@@ -45,7 +44,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -56,19 +54,16 @@
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.IRemoteCallback;
-import android.os.Message;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.provider.Settings.Secure;
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
 import android.util.ArraySet;
@@ -91,7 +86,7 @@
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.pip.tv.PipMenuActivity;
 import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsDebugFlags;
+import com.android.systemui.recents.RecentsDebugFlags.Static;
 import com.android.systemui.recents.RecentsImpl;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.ThumbnailData;
@@ -101,7 +96,6 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Random;
 
 /**
  * Acts as a shim around the real system services that we need to access data from, and provides
@@ -140,19 +134,17 @@
     UserManager mUm;
     Display mDisplay;
     String mRecentsPackage;
-    ComponentName mAssistComponent;
+    private TaskStackChangeListeners mTaskStackChangeListeners;
     private int mCurrentUserId;
 
     boolean mIsSafeMode;
-    boolean mHasFreeformWorkspaceSupport;
 
-    Bitmap mDummyIcon;
     int mDummyThumbnailWidth;
     int mDummyThumbnailHeight;
     Paint mBgProtectionPaint;
     Canvas mBgProtectionCanvas;
 
-    private final Handler mHandler = new H();
+    private final Handler mHandler = new Handler();
     private final Runnable mGcRunnable = new Runnable() {
         @Override
         public void run() {
@@ -163,144 +155,10 @@
 
     private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
 
-    /**
-     * An abstract class to track task stack changes.
-     * Classes should implement this instead of {@link android.app.ITaskStackListener}
-     * to reduce IPC calls from system services. These callbacks will be called on the main thread.
-     */
-    public abstract static class TaskStackListener {
-        /**
-         * NOTE: This call is made of the thread that the binder call comes in on.
-         */
-        public void onTaskStackChangedBackground() { }
-        public void onTaskStackChanged() { }
-        public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { }
-        public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { }
-        public void onActivityUnpinned() { }
-        public void onPinnedActivityRestartAttempt(boolean clearedTask) { }
-        public void onPinnedStackAnimationStarted() { }
-        public void onPinnedStackAnimationEnded() { }
-        public void onActivityForcedResizable(String packageName, int taskId, int reason) { }
-        public void onActivityDismissingDockedStack() { }
-        public void onActivityLaunchOnSecondaryDisplayFailed() { }
-        public void onTaskProfileLocked(int taskId, int userId) { }
-
-        /**
-         * Checks that the current user matches the user's SystemUI process. Since
-         * {@link android.app.ITaskStackListener} is not multi-user aware, handlers of
-         * TaskStackListener should make this call to verify that we don't act on events from other
-         * user's processes.
-         */
-        protected final boolean checkCurrentUserId(Context context, boolean debug) {
-            int processUserId = UserHandle.myUserId();
-            int currentUserId = SystemServicesProxy.getInstance(context).getCurrentUser();
-            if (processUserId != currentUserId) {
-                if (debug) {
-                    Log.d(TAG, "UID mismatch. SystemUI is running uid=" + processUserId
-                            + " and the current user is uid=" + currentUserId);
-                }
-                return false;
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Implementation of {@link android.app.ITaskStackListener} to listen task stack changes from
-     * ActivityManagerService.
-     * This simply passes callbacks to listeners through {@link H}.
-     * */
-    private android.app.TaskStackListener mTaskStackListener = new android.app.TaskStackListener() {
-
-        private final List<SystemServicesProxy.TaskStackListener> mTmpListeners = new ArrayList<>();
-
-        @Override
-        public void onTaskStackChanged() throws RemoteException {
-            // Call the task changed callback for the non-ui thread listeners first
-            synchronized (mTaskStackListeners) {
-                mTmpListeners.clear();
-                mTmpListeners.addAll(mTaskStackListeners);
-            }
-            for (int i = mTmpListeners.size() - 1; i >= 0; i--) {
-                mTmpListeners.get(i).onTaskStackChangedBackground();
-            }
-
-            mHandler.removeMessages(H.ON_TASK_STACK_CHANGED);
-            mHandler.sendEmptyMessage(H.ON_TASK_STACK_CHANGED);
-        }
-
-        @Override
-        public void onActivityPinned(String packageName, int userId, int taskId, int stackId)
-                throws RemoteException {
-            mHandler.removeMessages(H.ON_ACTIVITY_PINNED);
-            mHandler.obtainMessage(H.ON_ACTIVITY_PINNED,
-                    new PinnedActivityInfo(packageName, userId, taskId, stackId)).sendToTarget();
-        }
-
-        @Override
-        public void onActivityUnpinned() throws RemoteException {
-            mHandler.removeMessages(H.ON_ACTIVITY_UNPINNED);
-            mHandler.sendEmptyMessage(H.ON_ACTIVITY_UNPINNED);
-        }
-
-        @Override
-        public void onPinnedActivityRestartAttempt(boolean clearedTask)
-                throws RemoteException{
-            mHandler.removeMessages(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT);
-            mHandler.obtainMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT, clearedTask ? 1 : 0, 0)
-                    .sendToTarget();
-        }
-
-        @Override
-        public void onPinnedStackAnimationStarted() throws RemoteException {
-            mHandler.removeMessages(H.ON_PINNED_STACK_ANIMATION_STARTED);
-            mHandler.sendEmptyMessage(H.ON_PINNED_STACK_ANIMATION_STARTED);
-        }
-
-        @Override
-        public void onPinnedStackAnimationEnded() throws RemoteException {
-            mHandler.removeMessages(H.ON_PINNED_STACK_ANIMATION_ENDED);
-            mHandler.sendEmptyMessage(H.ON_PINNED_STACK_ANIMATION_ENDED);
-        }
-
-        @Override
-        public void onActivityForcedResizable(String packageName, int taskId, int reason)
-                throws RemoteException {
-            mHandler.obtainMessage(H.ON_ACTIVITY_FORCED_RESIZABLE, taskId, reason, packageName)
-                    .sendToTarget();
-        }
-
-        @Override
-        public void onActivityDismissingDockedStack() throws RemoteException {
-            mHandler.sendEmptyMessage(H.ON_ACTIVITY_DISMISSING_DOCKED_STACK);
-        }
-
-        @Override
-        public void onActivityLaunchOnSecondaryDisplayFailed() throws RemoteException {
-            mHandler.sendEmptyMessage(H.ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED);
-        }
-
-        @Override
-        public void onTaskProfileLocked(int taskId, int userId) {
-            mHandler.obtainMessage(H.ON_TASK_PROFILE_LOCKED, taskId, userId).sendToTarget();
-        }
-
-        @Override
-        public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot)
-                throws RemoteException {
-            mHandler.obtainMessage(H.ON_TASK_SNAPSHOT_CHANGED, taskId, 0, snapshot).sendToTarget();
-        }
-    };
-
     private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener =
             (String name, Drawable picture, String userAccount) ->
                     mCurrentUserId = mAm.getCurrentUser();
 
-    /**
-     * List of {@link TaskStackListener} registered from {@link #registerTaskStackListener}.
-     */
-    private List<TaskStackListener> mTaskStackListeners = new ArrayList<>();
-
     /** Private constructor */
     private SystemServicesProxy(Context context) {
         mContext = context.getApplicationContext();
@@ -319,12 +177,9 @@
                 ServiceManager.checkService(DreamService.DREAM_SERVICE));
         mDisplay = mWm.getDefaultDisplay();
         mRecentsPackage = context.getPackageName();
-        mHasFreeformWorkspaceSupport =
-                mPm.hasSystemFeature(PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT) ||
-                        Settings.Global.getInt(context.getContentResolver(),
-                                DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
         mIsSafeMode = mPm.isSafeMode();
         mCurrentUserId = mAm.getCurrentUser();
+        mTaskStackChangeListeners = new TaskStackChangeListeners(Looper.getMainLooper());
 
         // Get the dummy thumbnail width/heights
         Resources res = context.getResources();
@@ -339,21 +194,12 @@
         mBgProtectionPaint.setColor(0xFFffffff);
         mBgProtectionCanvas = new Canvas();
 
-        // Resolve the assist intent
-        mAssistComponent = mAssistUtils.getAssistComponentForUser(UserHandle.myUserId());
-
         // Since SystemServicesProxy can be accessed from a per-SysUI process component, create a
         // per-process listener to keep track of the current user id to reduce the number of binder
         // calls to fetch it.
         UserInfoController userInfoController = Dependency.get(UserInfoController.class);
         userInfoController.addCallback(mOnUserInfoChangedListener);
 
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            // Create a dummy icon
-            mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
-            mDummyIcon.eraseColor(0xFF999999);
-        }
-
         Collections.addAll(sRecentsBlacklist,
                 res.getStringArray(R.array.recents_blacklist_array));
     }
@@ -385,99 +231,28 @@
 
     /**
      * Returns a list of the recents tasks.
-     *
-     * @param includeFrontMostExcludedTask if set, will ensure that the front most excluded task
-     *                                     will be visible, otherwise no excluded tasks will be
-     *                                     visible.
      */
-    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numLatestTasks, int userId,
-            boolean includeFrontMostExcludedTask, ArraySet<Integer> quietProfileIds) {
+    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numTasks, int userId) {
         if (mAm == null) return null;
 
-        // If we are mocking, then create some recent tasks
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            ArrayList<ActivityManager.RecentTaskInfo> tasks =
-                    new ArrayList<ActivityManager.RecentTaskInfo>();
-            int count = Math.min(numLatestTasks, RecentsDebugFlags.Static.MockTaskCount);
-            for (int i = 0; i < count; i++) {
-                // Create a dummy component name
-                int packageIndex = i % RecentsDebugFlags.Static.MockTasksPackageCount;
-                ComponentName cn = new ComponentName("com.android.test" + packageIndex,
-                        "com.android.test" + i + ".Activity");
-                String description = "" + i + " - " +
-                        Long.toString(Math.abs(new Random().nextLong()), 36);
-                // Create the recent task info
-                ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
-                rti.id = rti.persistentId = rti.affiliatedTaskId = i;
-                rti.baseIntent = new Intent();
-                rti.baseIntent.setComponent(cn);
-                rti.description = description;
-                rti.firstActiveTime = rti.lastActiveTime = i;
-                if (i % 2 == 0) {
-                    rti.taskDescription = new ActivityManager.TaskDescription(description,
-                            Bitmap.createBitmap(mDummyIcon), null,
-                            0xFF000000 | (0xFFFFFF & new Random().nextInt()),
-                            0xFF000000 | (0xFFFFFF & new Random().nextInt()),
-                            0, 0);
-                } else {
-                    rti.taskDescription = new ActivityManager.TaskDescription();
+        try {
+            List<ActivityManager.RecentTaskInfo> tasks = mIam.getRecentTasks(numTasks,
+                    RECENT_IGNORE_UNAVAILABLE, userId).getList();
+            Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
+            while (iter.hasNext()) {
+                ActivityManager.RecentTaskInfo t = iter.next();
+
+                // Remove the task if it or it's package are blacklsited
+                if (sRecentsBlacklist.contains(t.realActivity.getClassName()) ||
+                        sRecentsBlacklist.contains(t.realActivity.getPackageName())) {
+                    iter.remove();
                 }
-                tasks.add(rti);
             }
             return tasks;
-        }
-
-        // Remove home/recents/excluded tasks
-        int minNumTasksToQuery = 10;
-        int numTasksToQuery = Math.max(minNumTasksToQuery, numLatestTasks);
-        int flags = ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS |
-                ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK |
-                ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS |
-                ActivityManager.RECENT_IGNORE_UNAVAILABLE |
-                ActivityManager.RECENT_INCLUDE_PROFILES;
-        if (includeFrontMostExcludedTask) {
-            flags |= ActivityManager.RECENT_WITH_EXCLUDED;
-        }
-        List<ActivityManager.RecentTaskInfo> tasks = null;
-        try {
-            tasks = mAm.getRecentTasksForUser(numTasksToQuery, flags, userId);
         } catch (Exception e) {
             Log.e(TAG, "Failed to get recent tasks", e);
-        }
-
-        // Break early if we can't get a valid set of tasks
-        if (tasks == null) {
             return new ArrayList<>();
         }
-
-        boolean isFirstValidTask = true;
-        Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
-        while (iter.hasNext()) {
-            ActivityManager.RecentTaskInfo t = iter.next();
-
-            // NOTE: The order of these checks happens in the expected order of the traversal of the
-            // tasks
-
-            // Remove the task if it or it's package are blacklsited
-            if (sRecentsBlacklist.contains(t.realActivity.getClassName()) ||
-                    sRecentsBlacklist.contains(t.realActivity.getPackageName())) {
-                iter.remove();
-                continue;
-            }
-
-            // Remove the task if it is marked as excluded, unless it is the first most task and we
-            // are requested to include it
-            boolean isExcluded = (t.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
-                    == Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
-            isExcluded |= quietProfileIds.contains(t.userId);
-            if (isExcluded && (!isFirstValidTask || !includeFrontMostExcludedTask)) {
-                iter.remove();
-            }
-
-            isFirstValidTask = false;
-        }
-
-        return tasks.subList(0, Math.min(tasks.size(), numLatestTasks));
     }
 
     /**
@@ -572,13 +347,6 @@
     }
 
     /**
-     * Returns whether this device has freeform workspaces.
-     */
-    public boolean hasFreeformWorkspaceSupport() {
-        return mHasFreeformWorkspaceSupport;
-    }
-
-    /**
      * Returns whether this device is in the safe mode.
      */
     public boolean isInSafeMode() {
@@ -646,7 +414,7 @@
      */
     public boolean hasSoftNavigationBar() {
         try {
-            return WindowManagerGlobal.getWindowManagerService().hasNavigationBar();
+            return mIwm.hasNavigationBar();
         } catch (RemoteException e) {
             e.printStackTrace();
         }
@@ -694,7 +462,7 @@
         if (mAm == null) return null;
 
         // If we are mocking, then just return a dummy thumbnail
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
+        if (Static.EnableTransitionThumbnailDebugMode) {
             ThumbnailData thumbnailData = new ThumbnailData();
             thumbnailData.thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth,
                     mDummyThumbnailHeight, Bitmap.Config.ARGB_8888);
@@ -715,7 +483,7 @@
 
         ActivityManager.TaskSnapshot snapshot = null;
         try {
-            snapshot = ActivityManager.getService().getTaskSnapshot(taskId, reducedResolution);
+            snapshot = mIam.getTaskSnapshot(taskId, reducedResolution);
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to retrieve snapshot", e);
         }
@@ -740,11 +508,14 @@
     /** Removes the task */
     public void removeTask(final int taskId) {
         if (mAm == null) return;
-        if (RecentsDebugFlags.Static.EnableMockTasks) return;
 
         // Remove the task.
         mUiOffloadThread.submit(() -> {
-            mAm.removeTask(taskId);
+            try {
+                mIam.removeTask(taskId);
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
         });
     }
 
@@ -768,7 +539,6 @@
      */
     public ActivityInfo getActivityInfo(ComponentName cn, int userId) {
         if (mIpm == null) return null;
-        if (RecentsDebugFlags.Static.EnableMockTasks) return new ActivityInfo();
 
         try {
             return mIpm.getActivityInfo(cn, PackageManager.GET_META_DATA, userId);
@@ -785,7 +555,6 @@
      */
     public ActivityInfo getActivityInfo(ComponentName cn) {
         if (mPm == null) return null;
-        if (RecentsDebugFlags.Static.EnableMockTasks) return new ActivityInfo();
 
         try {
             return mPm.getActivityInfo(cn, PackageManager.GET_META_DATA);
@@ -801,11 +570,6 @@
     public String getBadgedActivityLabel(ActivityInfo info, int userId) {
         if (mPm == null) return null;
 
-        // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            return "Recent Task: " + userId;
-        }
-
         return getBadgedLabel(info.loadLabel(mPm).toString(), userId);
     }
 
@@ -815,11 +579,6 @@
     public String getBadgedApplicationLabel(ApplicationInfo appInfo, int userId) {
         if (mPm == null) return null;
 
-        // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            return "Recent Task App: " + userId;
-        }
-
         return getBadgedLabel(appInfo.loadLabel(mPm).toString(), userId);
     }
 
@@ -829,11 +588,6 @@
      */
     public String getBadgedContentDescription(ActivityInfo info, int userId,
             ActivityManager.TaskDescription td, Resources res) {
-        // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            return "Recent Task Content Description: " + userId;
-        }
-
         String activityLabel;
         if (td != null && td.getLabel() != null) {
             activityLabel = td.getLabel();
@@ -854,11 +608,6 @@
     public Drawable getBadgedActivityIcon(ActivityInfo info, int userId) {
         if (mPm == null) return null;
 
-        // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            return new ColorDrawable(0xFF666666);
-        }
-
         return mDrawableFactory.getBadgedIcon(info, info.applicationInfo, userId);
     }
 
@@ -869,11 +618,6 @@
     public Drawable getBadgedApplicationIcon(ApplicationInfo appInfo, int userId) {
         if (mPm == null) return null;
 
-        // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            return new ColorDrawable(0xFF666666);
-        }
-
         return mDrawableFactory.getBadgedIcon(appInfo, userId);
     }
 
@@ -882,12 +626,6 @@
      */
     public Drawable getBadgedTaskDescriptionIcon(ActivityManager.TaskDescription taskDescription,
             int userId, Resources res) {
-
-        // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            return new ColorDrawable(0xFF666666);
-        }
-
         Bitmap tdIcon = taskDescription.getInMemoryIcon();
         if (tdIcon == null) {
             tdIcon = ActivityManager.TaskDescription.loadTaskDescriptionIcon(
@@ -923,32 +661,11 @@
     public Drawable getActivityBanner(ActivityInfo info) {
         if (mPm == null) return null;
 
-        // If we are mocking, then return a mock banner
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            return new ColorDrawable(0xFF666666);
-        }
-
         Drawable banner = info.loadBanner(mPm);
         return banner;
     }
 
     /**
-     * Returns a logo used on TV for the specified Activity.
-     */
-    public Drawable getActivityLogo(ActivityInfo info) {
-        if (mPm == null) return null;
-
-        // If we are mocking, then return a mock logo
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            return new ColorDrawable(0xFF666666);
-        }
-
-        Drawable logo = info.loadLogo(mPm);
-        return logo;
-    }
-
-
-    /**
      * Returns the given label for a user, badging if necessary.
      */
     private String getBadgedLabel(String label, int userId) {
@@ -968,24 +685,6 @@
         return mKgm.isDeviceLocked(userId);
     }
 
-    /** Returns the package name of the home activity. */
-    public String getHomeActivityPackageName() {
-        if (mPm == null) return null;
-        if (RecentsDebugFlags.Static.EnableMockTasks) return null;
-
-        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
-        ComponentName defaultHomeActivity = mPm.getHomeActivities(homeActivities);
-        if (defaultHomeActivity != null) {
-            return defaultHomeActivity.getPackageName();
-        } else if (homeActivities.size() == 1) {
-            ResolveInfo info = homeActivities.get(0);
-            if (info.activityInfo != null) {
-                return info.activityInfo.packageName;
-            }
-        }
-        return null;
-    }
-
     /**
      * Returns whether the provided {@param userId} represents the system user.
      */
@@ -1174,19 +873,11 @@
      * Registers a task stack listener with the system.
      * This should be called on the main thread.
      */
-    public void registerTaskStackListener(TaskStackListener listener) {
+    public void registerTaskStackListener(TaskStackChangeListener listener) {
         if (mIam == null) return;
 
-        synchronized (mTaskStackListeners) {
-            mTaskStackListeners.add(listener);
-            if (mTaskStackListeners.size() == 1) {
-                // Register mTaskStackListener to IActivityManager only once if needed.
-                try {
-                    mIam.registerTaskStackListener(mTaskStackListener);
-                } catch (Exception e) {
-                    Log.w(TAG, "Failed to call registerTaskStackListener", e);
-                }
-            }
+        synchronized (mTaskStackChangeListeners) {
+            mTaskStackChangeListeners.addListener(mIam, listener);
         }
     }
 
@@ -1195,7 +886,7 @@
             return;
         }
         try {
-            WindowManagerGlobal.getWindowManagerService().endProlongedAnimations();
+            mIwm.endProlongedAnimations();
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -1205,7 +896,7 @@
         if (mWm == null) return;
 
         try {
-            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(listener);
+            mIwm.registerDockedStackListener(listener);
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -1232,8 +923,7 @@
         if (mWm == null) return;
 
         try {
-            WindowManagerGlobal.getWindowManagerService().getStableInsets(Display.DEFAULT_DISPLAY,
-                    outStableInsets);
+            mIwm.getStableInsets(Display.DEFAULT_DISPLAY, outStableInsets);
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -1243,9 +933,7 @@
             IAppTransitionAnimationSpecsFuture future, IRemoteCallback animStartedListener,
             boolean scaleUp) {
         try {
-            WindowManagerGlobal.getWindowManagerService()
-                    .overridePendingAppTransitionMultiThumbFuture(future, animStartedListener,
-                            scaleUp);
+            mIwm.overridePendingAppTransitionMultiThumbFuture(future, animStartedListener, scaleUp);
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to override transition: " + e);
         }
@@ -1254,23 +942,27 @@
     /**
      * Updates the visibility of recents.
      */
-    public void setRecentsVisibility(boolean visible) {
-        try {
-            mIwm.setRecentsVisibility(visible);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Unable to reach window manager", e);
-        }
+    public void setRecentsVisibility(final boolean visible) {
+        mUiOffloadThread.submit(() -> {
+            try {
+                mIwm.setRecentsVisibility(visible);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Unable to reach window manager", e);
+            }
+        });
     }
 
     /**
      * Updates the visibility of the picture-in-picture.
      */
-    public void setPipVisibility(boolean visible) {
-        try {
-            mIwm.setPipVisibility(visible);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Unable to reach window manager", e);
-        }
+    public void setPipVisibility(final boolean visible) {
+        mUiOffloadThread.submit(() -> {
+            try {
+                mIwm.setPipVisibility(visible);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Unable to reach window manager", e);
+            }
+        });
     }
 
     public boolean isDreaming() {
@@ -1292,126 +984,7 @@
         });
     }
 
-    public void updateOverviewLastStackActiveTimeAsync(long newLastStackActiveTime,
-            int currentUserId) {
-        mUiOffloadThread.submit(() -> {
-            Settings.Secure.putLongForUser(mContext.getContentResolver(),
-                    Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, newLastStackActiveTime, currentUserId);
-        });
-    }
-
     public interface StartActivityFromRecentsResultListener {
         void onStartActivityResult(boolean succeeded);
     }
-
-    private class PinnedActivityInfo {
-        final String mPackageName;
-        final int mUserId;
-        final int mTaskId;
-        final int mStackId;
-
-        PinnedActivityInfo(String packageName, int userId, int taskId, int stackId) {
-            mPackageName = packageName;
-            mUserId = userId;
-            mTaskId = taskId;
-            mStackId = stackId;
-        }
-    }
-
-    private final class H extends Handler {
-        private static final int ON_TASK_STACK_CHANGED = 1;
-        private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
-        private static final int ON_ACTIVITY_PINNED = 3;
-        private static final int ON_PINNED_ACTIVITY_RESTART_ATTEMPT = 4;
-        private static final int ON_PINNED_STACK_ANIMATION_ENDED = 5;
-        private static final int ON_ACTIVITY_FORCED_RESIZABLE = 6;
-        private static final int ON_ACTIVITY_DISMISSING_DOCKED_STACK = 7;
-        private static final int ON_TASK_PROFILE_LOCKED = 8;
-        private static final int ON_PINNED_STACK_ANIMATION_STARTED = 9;
-        private static final int ON_ACTIVITY_UNPINNED = 10;
-        private static final int ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED = 11;
-
-        @Override
-        public void handleMessage(Message msg) {
-            synchronized (mTaskStackListeners) {
-                switch (msg.what) {
-                    case ON_TASK_STACK_CHANGED: {
-                    Trace.beginSection("onTaskStackChanged");
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onTaskStackChanged();
-                        }
-                    Trace.endSection();
-                        break;
-                    }
-                    case ON_TASK_SNAPSHOT_CHANGED: {
-                    Trace.beginSection("onTaskSnapshotChanged");
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1,
-                                    (TaskSnapshot) msg.obj);
-                        }
-                    Trace.endSection();
-                        break;
-                    }
-                    case ON_ACTIVITY_PINNED: {
-                        final PinnedActivityInfo info = (PinnedActivityInfo) msg.obj;
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onActivityPinned(
-                                    info.mPackageName, info.mUserId, info.mTaskId, info.mStackId);
-                        }
-                        break;
-                    }
-                    case ON_ACTIVITY_UNPINNED: {
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onActivityUnpinned();
-                        }
-                        break;
-                    }
-                    case ON_PINNED_ACTIVITY_RESTART_ATTEMPT: {
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onPinnedActivityRestartAttempt(
-                                    msg.arg1 != 0);
-                        }
-                        break;
-                    }
-                    case ON_PINNED_STACK_ANIMATION_STARTED: {
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onPinnedStackAnimationStarted();
-                        }
-                        break;
-                    }
-                    case ON_PINNED_STACK_ANIMATION_ENDED: {
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onPinnedStackAnimationEnded();
-                        }
-                        break;
-                    }
-                    case ON_ACTIVITY_FORCED_RESIZABLE: {
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onActivityForcedResizable(
-                                    (String) msg.obj, msg.arg1, msg.arg2);
-                        }
-                        break;
-                    }
-                    case ON_ACTIVITY_DISMISSING_DOCKED_STACK: {
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onActivityDismissingDockedStack();
-                        }
-                        break;
-                    }
-                    case ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED: {
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onActivityLaunchOnSecondaryDisplayFailed();
-                        }
-                        break;
-                    }
-                    case ON_TASK_PROFILE_LOCKED: {
-                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onTaskProfileLocked(msg.arg1, msg.arg2);
-                        }
-                        break;
-                    }
-                }
-            }
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/TaskStackChangeListener.java b/packages/SystemUI/src/com/android/systemui/recents/misc/TaskStackChangeListener.java
new file mode 100644
index 0000000..6d0952a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/TaskStackChangeListener.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 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.systemui.recents.misc;
+
+import android.app.ActivityManager.TaskSnapshot;
+import android.content.Context;
+import android.os.UserHandle;
+import android.util.Log;
+
+/**
+ * An abstract class to track task stack changes.
+ * Classes should implement this instead of {@link android.app.ITaskStackListener}
+ * to reduce IPC calls from system services. These callbacks will be called on the main thread.
+ */
+public abstract class TaskStackChangeListener {
+
+    /**
+     * NOTE: This call is made of the thread that the binder call comes in on.
+     */
+    public void onTaskStackChangedBackground() { }
+    public void onTaskStackChanged() { }
+    public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { }
+    public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { }
+    public void onActivityUnpinned() { }
+    public void onPinnedActivityRestartAttempt(boolean clearedTask) { }
+    public void onPinnedStackAnimationStarted() { }
+    public void onPinnedStackAnimationEnded() { }
+    public void onActivityForcedResizable(String packageName, int taskId, int reason) { }
+    public void onActivityDismissingDockedStack() { }
+    public void onActivityLaunchOnSecondaryDisplayFailed() { }
+    public void onTaskProfileLocked(int taskId, int userId) { }
+
+    /**
+     * Checks that the current user matches the user's SystemUI process. Since
+     * {@link android.app.ITaskStackListener} is not multi-user aware, handlers of
+     * TaskStackChangeListener should make this call to verify that we don't act on events from other
+     * user's processes.
+     */
+    protected final boolean checkCurrentUserId(Context context, boolean debug) {
+        int processUserId = UserHandle.myUserId();
+        int currentUserId = SystemServicesProxy.getInstance(context).getCurrentUser();
+        if (processUserId != currentUserId) {
+            if (debug) {
+                Log.d(SystemServicesProxy.TAG, "UID mismatch. SystemUI is running uid=" + processUserId
+                        + " and the current user is uid=" + currentUserId);
+            }
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/TaskStackChangeListeners.java b/packages/SystemUI/src/com/android/systemui/recents/misc/TaskStackChangeListeners.java
new file mode 100644
index 0000000..8eb70f0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/TaskStackChangeListeners.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2017 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.systemui.recents.misc;
+
+import android.app.ActivityManager.TaskSnapshot;
+import android.app.IActivityManager;
+import android.app.TaskStackListener;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.Trace;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tracks all the task stack listeners
+ */
+public class TaskStackChangeListeners extends TaskStackListener {
+
+    private static final String TAG = TaskStackChangeListeners.class.getSimpleName();
+
+    /**
+     * List of {@link TaskStackChangeListener} registered from {@link #addListener}.
+     */
+    private final List<TaskStackChangeListener> mTaskStackListeners = new ArrayList<>();
+    private final List<TaskStackChangeListener> mTmpListeners = new ArrayList<>();
+
+    private final Handler mHandler;
+
+    public TaskStackChangeListeners(Looper looper) {
+        mHandler = new H(looper);
+    }
+
+    public void addListener(IActivityManager am, TaskStackChangeListener listener) {
+        mTaskStackListeners.add(listener);
+        if (mTaskStackListeners.size() == 1) {
+            // Register mTaskStackListener to IActivityManager only once if needed.
+            try {
+                am.registerTaskStackListener(this);
+            } catch (Exception e) {
+                Log.w(TAG, "Failed to call registerTaskStackListener", e);
+            }
+        }
+    }
+
+    @Override
+    public void onTaskStackChanged() throws RemoteException {
+        // Call the task changed callback for the non-ui thread listeners first
+        synchronized (mTaskStackListeners) {
+            mTmpListeners.clear();
+            mTmpListeners.addAll(mTaskStackListeners);
+        }
+        for (int i = mTmpListeners.size() - 1; i >= 0; i--) {
+            mTmpListeners.get(i).onTaskStackChangedBackground();
+        }
+
+        mHandler.removeMessages(H.ON_TASK_STACK_CHANGED);
+        mHandler.sendEmptyMessage(H.ON_TASK_STACK_CHANGED);
+    }
+
+    @Override
+    public void onActivityPinned(String packageName, int userId, int taskId, int stackId)
+            throws RemoteException {
+        mHandler.removeMessages(H.ON_ACTIVITY_PINNED);
+        mHandler.obtainMessage(H.ON_ACTIVITY_PINNED,
+                new PinnedActivityInfo(packageName, userId, taskId, stackId)).sendToTarget();
+    }
+
+    @Override
+    public void onActivityUnpinned() throws RemoteException {
+        mHandler.removeMessages(H.ON_ACTIVITY_UNPINNED);
+        mHandler.sendEmptyMessage(H.ON_ACTIVITY_UNPINNED);
+    }
+
+    @Override
+    public void onPinnedActivityRestartAttempt(boolean clearedTask)
+            throws RemoteException{
+        mHandler.removeMessages(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT);
+        mHandler.obtainMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT, clearedTask ? 1 : 0, 0)
+                .sendToTarget();
+    }
+
+    @Override
+    public void onPinnedStackAnimationStarted() throws RemoteException {
+        mHandler.removeMessages(H.ON_PINNED_STACK_ANIMATION_STARTED);
+        mHandler.sendEmptyMessage(H.ON_PINNED_STACK_ANIMATION_STARTED);
+    }
+
+    @Override
+    public void onPinnedStackAnimationEnded() throws RemoteException {
+        mHandler.removeMessages(H.ON_PINNED_STACK_ANIMATION_ENDED);
+        mHandler.sendEmptyMessage(H.ON_PINNED_STACK_ANIMATION_ENDED);
+    }
+
+    @Override
+    public void onActivityForcedResizable(String packageName, int taskId, int reason)
+            throws RemoteException {
+        mHandler.obtainMessage(H.ON_ACTIVITY_FORCED_RESIZABLE, taskId, reason, packageName)
+                .sendToTarget();
+    }
+
+    @Override
+    public void onActivityDismissingDockedStack() throws RemoteException {
+        mHandler.sendEmptyMessage(H.ON_ACTIVITY_DISMISSING_DOCKED_STACK);
+    }
+
+    @Override
+    public void onActivityLaunchOnSecondaryDisplayFailed() throws RemoteException {
+        mHandler.sendEmptyMessage(H.ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED);
+    }
+
+    @Override
+    public void onTaskProfileLocked(int taskId, int userId) throws RemoteException {
+        mHandler.obtainMessage(H.ON_TASK_PROFILE_LOCKED, taskId, userId).sendToTarget();
+    }
+
+    @Override
+    public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot)
+            throws RemoteException {
+        mHandler.obtainMessage(H.ON_TASK_SNAPSHOT_CHANGED, taskId, 0, snapshot).sendToTarget();
+    }
+
+    private final class H extends Handler {
+        private static final int ON_TASK_STACK_CHANGED = 1;
+        private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
+        private static final int ON_ACTIVITY_PINNED = 3;
+        private static final int ON_PINNED_ACTIVITY_RESTART_ATTEMPT = 4;
+        private static final int ON_PINNED_STACK_ANIMATION_ENDED = 5;
+        private static final int ON_ACTIVITY_FORCED_RESIZABLE = 6;
+        private static final int ON_ACTIVITY_DISMISSING_DOCKED_STACK = 7;
+        private static final int ON_TASK_PROFILE_LOCKED = 8;
+        private static final int ON_PINNED_STACK_ANIMATION_STARTED = 9;
+        private static final int ON_ACTIVITY_UNPINNED = 10;
+        private static final int ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED = 11;
+
+        public H(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            synchronized (mTaskStackListeners) {
+                switch (msg.what) {
+                    case ON_TASK_STACK_CHANGED: {
+                        Trace.beginSection("onTaskStackChanged");
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onTaskStackChanged();
+                        }
+                        Trace.endSection();
+                        break;
+                    }
+                    case ON_TASK_SNAPSHOT_CHANGED: {
+                        Trace.beginSection("onTaskSnapshotChanged");
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1,
+                                    (TaskSnapshot) msg.obj);
+                        }
+                        Trace.endSection();
+                        break;
+                    }
+                    case ON_ACTIVITY_PINNED: {
+                        final PinnedActivityInfo info = (PinnedActivityInfo) msg.obj;
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityPinned(
+                                    info.mPackageName, info.mUserId, info.mTaskId, info.mStackId);
+                        }
+                        break;
+                    }
+                    case ON_ACTIVITY_UNPINNED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityUnpinned();
+                        }
+                        break;
+                    }
+                    case ON_PINNED_ACTIVITY_RESTART_ATTEMPT: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onPinnedActivityRestartAttempt(
+                                    msg.arg1 != 0);
+                        }
+                        break;
+                    }
+                    case ON_PINNED_STACK_ANIMATION_STARTED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onPinnedStackAnimationStarted();
+                        }
+                        break;
+                    }
+                    case ON_PINNED_STACK_ANIMATION_ENDED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onPinnedStackAnimationEnded();
+                        }
+                        break;
+                    }
+                    case ON_ACTIVITY_FORCED_RESIZABLE: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityForcedResizable(
+                                    (String) msg.obj, msg.arg1, msg.arg2);
+                        }
+                        break;
+                    }
+                    case ON_ACTIVITY_DISMISSING_DOCKED_STACK: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityDismissingDockedStack();
+                        }
+                        break;
+                    }
+                    case ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityLaunchOnSecondaryDisplayFailed();
+                        }
+                        break;
+                    }
+                    case ON_TASK_PROFILE_LOCKED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onTaskProfileLocked(msg.arg1, msg.arg2);
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    private static class PinnedActivityInfo {
+        final String mPackageName;
+        final int mUserId;
+        final int mTaskId;
+        final int mStackId;
+
+        PinnedActivityInfo(String packageName, int userId, int taskId, int stackId) {
+            mPackageName = packageName;
+            mUserId = userId;
+            mTaskId = taskId;
+            mStackId = stackId;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
deleted file mode 100644
index 308cece..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.model;
-
-import android.content.Context;
-import android.os.UserHandle;
-
-import com.android.internal.content.PackageMonitor;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.PackagesChangedEvent;
-import com.android.systemui.recents.misc.ForegroundThread;
-
-/**
- * The package monitor listens for changes from PackageManager to update the contents of the
- * Recents list.
- */
-public class RecentsPackageMonitor extends PackageMonitor {
-
-    /** Registers the broadcast receivers with the specified callbacks. */
-    public void register(Context context) {
-        try {
-            // We register for events from all users, but will cross-reference them with
-            // packages for the current user and any profiles they have.  Ensure that events are
-            // handled in a background thread.
-            register(context, ForegroundThread.get().getLooper(), UserHandle.ALL, true);
-        } catch (IllegalStateException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /** Unregisters the broadcast receivers. */
-    @Override
-    public void unregister() {
-        try {
-            super.unregister();
-        } catch (IllegalStateException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    public void onPackageRemoved(String packageName, int uid) {
-        // Notify callbacks on the main thread that a package has changed
-        final int eventUserId = getChangingUserId();
-        EventBus.getDefault().post(new PackagesChangedEvent(this, packageName, eventUserId));
-    }
-
-    @Override
-    public boolean onPackageChanged(String packageName, int uid, String[] components) {
-        onPackageModified(packageName);
-        return true;
-    }
-
-    @Override
-    public void onPackageModified(String packageName) {
-        // Notify callbacks on the main thread that a package has changed
-        final int eventUserId = getChangingUserId();
-        EventBus.getDefault().post(new PackagesChangedEvent(this, packageName, eventUserId));
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index d5e0313..62ba30b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -57,10 +57,6 @@
  */
 public class RecentsTaskLoadPlan {
 
-    private static int MIN_NUM_TASKS = 5;
-    private static int SESSION_BEGIN_TIME = 1000 /* ms/s */ * 60 /* s/min */ * 60 /* min/hr */ *
-            6 /* hrs */;
-
     /** The set of conditions to load tasks. */
     public static class Options {
         public int runningTaskId = -1;
@@ -74,44 +70,24 @@
 
     Context mContext;
 
-    int mPreloadedUserId;
     List<ActivityManager.RecentTaskInfo> mRawTasks;
     TaskStack mStack;
-    ArraySet<Integer> mCurrentQuietProfiles = new ArraySet<Integer>();
 
     /** Package level ctor */
     RecentsTaskLoadPlan(Context context) {
         mContext = context;
     }
 
-    private void updateCurrentQuietProfilesCache(int currentUserId) {
-        mCurrentQuietProfiles.clear();
-
-        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        List<UserInfo> profiles = userManager.getProfiles(currentUserId);
-        if (profiles != null) {
-            for (int i = 0; i < profiles.size(); i++) {
-                UserInfo user  = profiles.get(i);
-                if (user.isManagedProfile() && user.isQuietModeEnabled()) {
-                    mCurrentQuietProfiles.add(user.id);
-                }
-            }
-        }
-    }
-
     /**
      * An optimization to preload the raw list of tasks. The raw tasks are saved in least-recent
      * to most-recent order.
      *
      * Note: Do not lock, callers should synchronize on the loader before making this call.
      */
-    void preloadRawTasks(boolean includeFrontMostExcludedTask) {
+    void preloadRawTasks() {
         SystemServicesProxy ssp = Recents.getSystemServices();
         int currentUserId = ssp.getCurrentUser();
-        updateCurrentQuietProfilesCache(currentUserId);
-        mPreloadedUserId = currentUserId;
-        mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(),
-                currentUserId, includeFrontMostExcludedTask, mCurrentQuietProfiles);
+        mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), currentUserId);
 
         // Since the raw tasks are given in most-recent to least-recent order, we need to reverse it
         Collections.reverse(mRawTasks);
@@ -124,34 +100,22 @@
      *
      * The tasks will be ordered by:
      * - least-recent to most-recent stack tasks
-     * - least-recent to most-recent freeform tasks
      *
      * Note: Do not lock, since this can be calling back to the loader, which separately also drives
      * this call (callers should synchronize on the loader before making this call).
      */
-    void preloadPlan(RecentsTaskLoader loader, int runningTaskId,
-            boolean includeFrontMostExcludedTask) {
+    void preloadPlan(RecentsTaskLoader loader, int runningTaskId) {
         Resources res = mContext.getResources();
         ArrayList<Task> allTasks = new ArrayList<>();
         if (mRawTasks == null) {
-            preloadRawTasks(includeFrontMostExcludedTask);
+            preloadRawTasks();
         }
 
-        SparseArray<Task.TaskKey> affiliatedTasks = new SparseArray<>();
-        SparseIntArray affiliatedTaskCounts = new SparseIntArray();
         SparseBooleanArray lockedUsers = new SparseBooleanArray();
         String dismissDescFormat = mContext.getString(
                 R.string.accessibility_recents_item_will_be_dismissed);
         String appInfoDescFormat = mContext.getString(
                 R.string.accessibility_recents_item_open_app_info);
-        int currentUserId = mPreloadedUserId;
-        long legacyLastStackActiveTime = migrateLegacyLastStackActiveTime(currentUserId);
-        long lastStackActiveTime = Settings.Secure.getLongForUser(mContext.getContentResolver(),
-                Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, legacyLastStackActiveTime, currentUserId);
-        if (RecentsDebugFlags.Static.EnableMockTasks) {
-            lastStackActiveTime = 0;
-        }
-        long newLastStackActiveTime = -1;
         int taskCount = mRawTasks.size();
         for (int i = 0; i < taskCount; i++) {
             ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
@@ -159,35 +123,12 @@
             // Compose the task key
             final int windowingMode = t.configuration.windowConfiguration.getWindowingMode();
             Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, windowingMode, t.baseIntent,
-                    t.userId, t.firstActiveTime, t.lastActiveTime);
+                    t.userId, t.lastActiveTime);
 
-            // This task is only shown in the stack if it satisfies the historical time or min
-            // number of tasks constraints. Freeform tasks are also always shown.
             boolean isFreeformTask = windowingMode == WINDOWING_MODE_FREEFORM;
-            boolean isStackTask;
-            if (Recents.getConfiguration().isGridEnabled) {
-                // When grid layout is enabled, we only show the first
-                // TaskGridLayoutAlgorithm.MAX_LAYOUT_FROM_HOME_TASK_COUNT} tasks.
-                isStackTask = t.lastActiveTime >= lastStackActiveTime &&
-                    i >= taskCount - TaskGridLayoutAlgorithm.MAX_LAYOUT_TASK_COUNT;
-            } else if (Recents.getConfiguration().isLowRamDevice) {
-                // Show a max of 3 items
-                isStackTask = t.lastActiveTime >= lastStackActiveTime &&
-                        i >= taskCount - TaskStackLowRamLayoutAlgorithm.MAX_LAYOUT_TASK_COUNT;
-            } else {
-                isStackTask = isFreeformTask || !isHistoricalTask(t) ||
-                    (t.lastActiveTime >= lastStackActiveTime && i >= (taskCount - MIN_NUM_TASKS));
-            }
+            boolean isStackTask = !isFreeformTask;
             boolean isLaunchTarget = taskKey.id == runningTaskId;
 
-            // The last stack active time is the baseline for which we show visible tasks.  Since
-            // the system will store all the tasks, we don't want to show the tasks prior to the
-            // last visible ones, otherwise, as you dismiss them, the previous tasks may satisfy
-            // the other stack-task constraints.
-            if (isStackTask && newLastStackActiveTime < 0) {
-                newLastStackActiveTime = t.lastActiveTime;
-            }
-
             // Load the title, icon, and color
             ActivityInfo info = loader.getAndUpdateActivityInfo(taskKey);
             String title = loader.getAndUpdateActivityTitle(taskKey, t.taskDescription);
@@ -210,24 +151,18 @@
             boolean isLocked = lockedUsers.get(t.userId);
 
             // Add the task to the stack
-            Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, icon,
+            Task task = new Task(taskKey, icon,
                     thumbnail, title, titleDescription, dismissDescription, appInfoDescription,
                     activityColor, backgroundColor, isLaunchTarget, isStackTask, isSystemApp,
-                    t.supportsSplitScreenMultiWindow, t.bounds, t.taskDescription, t.resizeMode, t.topActivity,
-                    isLocked);
+                    t.supportsSplitScreenMultiWindow, t.taskDescription, t.resizeMode,
+                    t.topActivity, isLocked);
 
             allTasks.add(task);
-            affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1);
-            affiliatedTasks.put(taskKey.id, taskKey);
-        }
-        if (newLastStackActiveTime != -1) {
-            Recents.getSystemServices().updateOverviewLastStackActiveTimeAsync(
-                    newLastStackActiveTime, currentUserId);
         }
 
         // Initialize the stacks
         mStack = new TaskStack();
-        mStack.setTasks(mContext, allTasks, false /* notifyStackChanges */);
+        mStack.setTasks(allTasks, false /* notifyStackChanges */);
     }
 
     /**
@@ -289,42 +224,4 @@
         }
         return false;
     }
-
-    /**
-     * Returns whether this task is too old to be shown.
-     */
-    private boolean isHistoricalTask(ActivityManager.RecentTaskInfo t) {
-        return t.lastActiveTime < (System.currentTimeMillis() - SESSION_BEGIN_TIME);
-    }
-
-
-    /**
-     * Migrate the last active time from the prefs to the secure settings.
-     *
-     * The first time this runs, it will:
-     * 1) fetch the last stack active time from the prefs
-     * 2) set the prefs to the last stack active time for all users
-     * 3) clear the pref
-     * 4) return the last stack active time
-     *
-     * Subsequent calls to this will return zero.
-     */
-    private long migrateLegacyLastStackActiveTime(int currentUserId) {
-        long legacyLastStackActiveTime = Prefs.getLong(mContext,
-                Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, -1);
-        if (legacyLastStackActiveTime != -1) {
-            Prefs.remove(mContext, Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME);
-            UserManager userMgr = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-            List<UserInfo> users = userMgr.getUsers();
-            for (int i = 0; i < users.size(); i++) {
-                int userId = users.get(i).id;
-                if (userId != currentUserId) {
-                    Recents.getSystemServices().updateOverviewLastStackActiveTimeAsync(
-                            legacyLastStackActiveTime, userId);
-                }
-            }
-            return legacyLastStackActiveTime;
-        }
-        return 0;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index 1b89386..3494a00 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -256,7 +256,7 @@
     // This activity info LruCache is useful because it can be expensive to retrieve ActivityInfos
     // for many tasks, which we use to get the activity labels and icons.  Unlike the other caches
     // below, this is per-package so we can't invalidate the items in the cache based on the last
-    // active time.  Instead, we rely on the RecentsPackageMonitor to keep us informed whenever a
+    // active time.  Instead, we rely on the PackageMonitor to keep us informed whenever a
     // package in the cache has been updated, so that we may remove it.
     private final LruCache<ComponentName, ActivityInfo> mActivityInfoCache;
     private final TaskKeyLruCache<Drawable> mIconCache;
@@ -295,8 +295,6 @@
                 context.getColor(R.color.recents_task_view_default_background_color);
         mMaxThumbnailCacheSize = res.getInteger(R.integer.config_recents_max_thumbnail_count);
         mMaxIconCacheSize = res.getInteger(R.integer.config_recents_max_icon_count);
-        int iconCacheSize = RecentsDebugFlags.Static.DisableBackgroundCache ? 1 :
-                mMaxIconCacheSize;
 
         // Create the default assets
         Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
@@ -308,7 +306,7 @@
         mHighResThumbnailLoader = new HighResThumbnailLoader(Recents.getSystemServices(),
                 Looper.getMainLooper(), Recents.getConfiguration().isLowRamDevice);
         mLoadQueue = new TaskResourceLoadQueue();
-        mIconCache = new TaskKeyLruCache<>(iconCacheSize, mClearActivityInfoOnEviction);
+        mIconCache = new TaskKeyLruCache<>(mMaxIconCacheSize, mClearActivityInfoOnEviction);
         mActivityLabelCache = new TaskKeyLruCache<>(numRecentTasks, mClearActivityInfoOnEviction);
         mContentDescriptionCache = new TaskKeyLruCache<>(numRecentTasks,
                 mClearActivityInfoOnEviction);
@@ -337,18 +335,11 @@
         return plan;
     }
 
-    /** Preloads raw recents tasks using the specified plan to store the output. */
-    public synchronized void preloadRawTasks(RecentsTaskLoadPlan plan,
-            boolean includeFrontMostExcludedTask) {
-        plan.preloadRawTasks(includeFrontMostExcludedTask);
-    }
-
     /** Preloads recents tasks using the specified plan to store the output. */
-    public synchronized void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId,
-            boolean includeFrontMostExcludedTask) {
+    public synchronized void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId) {
         try {
             Trace.beginSection("preloadPlan");
-            plan.preloadPlan(this, runningTaskId, includeFrontMostExcludedTask);
+            plan.preloadPlan(this, runningTaskId);
         } finally {
             Trace.endSection();
         }
@@ -444,6 +435,21 @@
         }
     }
 
+    public void onPackageChanged(String packageName) {
+        // Remove all the cached activity infos for this package.  The other caches do not need to
+        // be pruned at this time, as the TaskKey expiration checks will flush them next time their
+        // cached contents are requested
+        Map<ComponentName, ActivityInfo> activityInfoCache = mActivityInfoCache.snapshot();
+        for (ComponentName cn : activityInfoCache.keySet()) {
+            if (cn.getPackageName().equals(packageName)) {
+                if (DEBUG) {
+                    Log.d(TAG, "Removing activity info from cache: " + cn);
+                }
+                mActivityInfoCache.remove(cn);
+            }
+        }
+    }
+
     /**
      * Returns the cached task label if the task key is not expired, updating the cache if it is.
      */
@@ -632,23 +638,6 @@
         mLoadQueue.clearTasks();
     }
 
-    /**** Event Bus Events ****/
-
-    public final void onBusEvent(PackagesChangedEvent event) {
-        // Remove all the cached activity infos for this package.  The other caches do not need to
-        // be pruned at this time, as the TaskKey expiration checks will flush them next time their
-        // cached contents are requested
-        Map<ComponentName, ActivityInfo> activityInfoCache = mActivityInfoCache.snapshot();
-        for (ComponentName cn : activityInfoCache.keySet()) {
-            if (cn.getPackageName().equals(event.packageName)) {
-                if (DEBUG) {
-                    Log.d(TAG, "Removing activity info from cache: " + cn);
-                }
-                mActivityInfoCache.remove(cn);
-            }
-        }
-    }
-
     public synchronized void dump(String prefix, PrintWriter writer) {
         String innerPrefix = prefix + "  ";
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index abdb5cb..ae417c0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 
 import android.app.ActivityManager;
+import android.app.ActivityManager.TaskDescription;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -69,13 +70,11 @@
 
         private int mHashCode;
 
-        public TaskKey(int id, int windowingMode, Intent intent, int userId, long firstActiveTime,
-                long lastActiveTime) {
+        public TaskKey(int id, int windowingMode, Intent intent, int userId, long lastActiveTime) {
             this.id = id;
             this.windowingMode = windowingMode;
             this.baseIntent = intent;
             this.userId = userId;
-            this.firstActiveTime = firstActiveTime;
             this.lastActiveTime = lastActiveTime;
             updateHashCode();
         }
@@ -125,20 +124,6 @@
     public int temporarySortIndexInStack;
 
     /**
-     * The group will be computed separately from the initialization of the task
-     */
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="group_")
-    public TaskGrouping group;
-    /**
-     * The affiliationTaskId is the task id of the parent task or itself if it is not affiliated
-     * with any task.
-     */
-    @ViewDebug.ExportedProperty(category="recents")
-    public int affiliationTaskId;
-    @ViewDebug.ExportedProperty(category="recents")
-    public int affiliationColor;
-
-    /**
      * The icon is the task description icon (if provided), which falls back to the activity icon,
      * which can then fall back to the application icon.
      */
@@ -160,15 +145,9 @@
     public boolean useLightOnPrimaryColor;
 
     /**
-     * The bounds of the task, used only if it is a freeform task.
-     */
-    @ViewDebug.ExportedProperty(category="recents")
-    public Rect bounds;
-
-    /**
      * The task description for this task, only used to reload task icons.
      */
-    public ActivityManager.TaskDescription taskDescription;
+    public TaskDescription taskDescription;
 
     /**
      * The state isLaunchTarget will be set for the correct task upon launching Recents.
@@ -200,28 +179,22 @@
         // Do nothing
     }
 
-    public Task(TaskKey key, int affiliationTaskId, int affiliationColor, Drawable icon,
-            ThumbnailData thumbnail, String title, String titleDescription,
-            String dismissDescription, String appInfoDescription, int colorPrimary,
-            int colorBackground, boolean isLaunchTarget, boolean isStackTask, boolean isSystemApp,
-            boolean isDockable, Rect bounds, ActivityManager.TaskDescription taskDescription,
+    public Task(TaskKey key, Drawable icon, ThumbnailData thumbnail, String title,
+            String titleDescription, String dismissDescription, String appInfoDescription,
+            int colorPrimary, int colorBackground, boolean isLaunchTarget, boolean isStackTask,
+            boolean isSystemApp, boolean isDockable, TaskDescription taskDescription,
             int resizeMode, ComponentName topActivity, boolean isLocked) {
-        boolean isInAffiliationGroup = (affiliationTaskId != key.id);
-        boolean hasAffiliationGroupColor = isInAffiliationGroup && (affiliationColor != 0);
         this.key = key;
-        this.affiliationTaskId = affiliationTaskId;
-        this.affiliationColor = affiliationColor;
         this.icon = icon;
         this.thumbnail = thumbnail;
         this.title = title;
         this.titleDescription = titleDescription;
         this.dismissDescription = dismissDescription;
         this.appInfoDescription = appInfoDescription;
-        this.colorPrimary = hasAffiliationGroupColor ? affiliationColor : colorPrimary;
+        this.colorPrimary = colorPrimary;
         this.colorBackground = colorBackground;
         this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary,
                 Color.WHITE) > 3f;
-        this.bounds = bounds;
         this.taskDescription = taskDescription;
         this.isLaunchTarget = isLaunchTarget;
         this.isStackTask = isStackTask;
@@ -237,9 +210,6 @@
      */
     public void copyFrom(Task o) {
         this.key = o.key;
-        this.group = o.group;
-        this.affiliationTaskId = o.affiliationTaskId;
-        this.affiliationColor = o.affiliationColor;
         this.icon = o.icon;
         this.thumbnail = o.thumbnail;
         this.title = o.title;
@@ -249,7 +219,6 @@
         this.colorPrimary = o.colorPrimary;
         this.colorBackground = o.colorBackground;
         this.useLightOnPrimaryColor = o.useLightOnPrimaryColor;
-        this.bounds = o.bounds;
         this.taskDescription = o.taskDescription;
         this.isLaunchTarget = o.isLaunchTarget;
         this.isStackTask = o.isStackTask;
@@ -276,11 +245,6 @@
         mCallbacks.remove(cb);
     }
 
-    /** Set the grouping */
-    public void setGroup(TaskGrouping group) {
-        this.group = group;
-    }
-
     /** Updates the task's windowing mode. */
     public void setWindowingMode(int windowingMode) {
         key.setWindowingMode(windowingMode);
@@ -290,14 +254,6 @@
         }
     }
 
-    /**
-     * Returns whether this task is on the freeform task stack.
-     */
-    public boolean isFreeformTask() {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        return ssp.hasFreeformWorkspaceSupport() && key.windowingMode == WINDOWING_MODE_FREEFORM;
-    }
-
     /** Notifies the callback listeners that this task has been loaded */
     public void notifyTaskDataLoaded(ThumbnailData thumbnailData, Drawable applicationIcon) {
         this.icon = applicationIcon;
@@ -318,13 +274,6 @@
     }
 
     /**
-     * Returns whether this task is affiliated with another task.
-     */
-    public boolean isAffiliatedTask() {
-        return key.id != affiliationTaskId;
-    }
-
-    /**
      * Returns the top activity component.
      */
     public ComponentName getTopComponent() {
@@ -347,18 +296,12 @@
 
     public void dump(String prefix, PrintWriter writer) {
         writer.print(prefix); writer.print(key);
-        if (isAffiliatedTask()) {
-            writer.print(" "); writer.print("affTaskId=" + affiliationTaskId);
-        }
         if (!isDockable) {
             writer.print(" dockable=N");
         }
         if (isLaunchTarget) {
             writer.print(" launchTarget=Y");
         }
-        if (isFreeformTask()) {
-            writer.print(" freeform=Y");
-        }
         if (isLocked) {
             writer.print(" locked=Y");
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java
deleted file mode 100644
index 2109376..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.android.systemui.recents.model;
-
-import android.util.ArrayMap;
-
-import java.util.ArrayList;
-
-/** Represents a grouping of tasks witihin a stack. */
-public class TaskGrouping {
-
-    int affiliation;
-    long latestActiveTimeInGroup;
-
-    Task.TaskKey mFrontMostTaskKey;
-    ArrayList<Task.TaskKey> mTaskKeys = new ArrayList<Task.TaskKey>();
-    ArrayMap<Task.TaskKey, Integer> mTaskKeyIndices = new ArrayMap<>();
-
-    /** Creates a group with a specified affiliation. */
-    public TaskGrouping(int affiliation) {
-        this.affiliation = affiliation;
-    }
-
-    /** Adds a new task to this group. */
-    void addTask(Task t) {
-        mTaskKeys.add(t.key);
-        if (t.key.lastActiveTime > latestActiveTimeInGroup) {
-            latestActiveTimeInGroup = t.key.lastActiveTime;
-        }
-        t.setGroup(this);
-        updateTaskIndices();
-    }
-
-    /** Removes a task from this group. */
-    void removeTask(Task t) {
-        mTaskKeys.remove(t.key);
-        latestActiveTimeInGroup = 0;
-        int taskCount = mTaskKeys.size();
-        for (int i = 0; i < taskCount; i++) {
-            long lastActiveTime = mTaskKeys.get(i).lastActiveTime;
-            if (lastActiveTime > latestActiveTimeInGroup) {
-                latestActiveTimeInGroup = lastActiveTime;
-            }
-        }
-        t.setGroup(null);
-        updateTaskIndices();
-    }
-
-    /** Returns the key of the next task in the group. */
-    public Task.TaskKey getNextTaskInGroup(Task t) {
-        int i = indexOf(t);
-        if ((i + 1) < getTaskCount()) {
-            return mTaskKeys.get(i + 1);
-        }
-        return null;
-    }
-
-    /** Returns the key of the previous task in the group. */
-    public Task.TaskKey getPrevTaskInGroup(Task t) {
-        int i = indexOf(t);
-        if ((i - 1) >= 0) {
-            return mTaskKeys.get(i - 1);
-        }
-        return null;
-    }
-
-    /** Gets the front task */
-    public boolean isFrontMostTask(Task t) {
-        return (t.key == mFrontMostTaskKey);
-    }
-
-    /** Finds the index of a given task in a group. */
-    public int indexOf(Task t) {
-        return mTaskKeyIndices.get(t.key);
-    }
-
-    /** Returns whether a task is in this grouping. */
-    public boolean containsTask(Task t) {
-        return mTaskKeyIndices.containsKey(t.key);
-    }
-
-    /** Returns whether one task is above another in the group.  If they are not in the same group,
-     * this returns false. */
-    public boolean isTaskAboveTask(Task t, Task below) {
-        return mTaskKeyIndices.containsKey(t.key) && mTaskKeyIndices.containsKey(below.key) &&
-                mTaskKeyIndices.get(t.key) > mTaskKeyIndices.get(below.key);
-    }
-
-    /** Returns the number of tasks in this group. */
-    public int getTaskCount() { return mTaskKeys.size(); }
-
-    /** Updates the mapping of tasks to indices. */
-    private void updateTaskIndices() {
-        if (mTaskKeys.isEmpty()) {
-            mFrontMostTaskKey = null;
-            mTaskKeyIndices.clear();
-            return;
-        }
-
-        int taskCount = mTaskKeys.size();
-        mFrontMostTaskKey = mTaskKeys.get(mTaskKeys.size() - 1);
-        mTaskKeyIndices.clear();
-        for (int i = 0; i < taskCount; i++) {
-            Task.TaskKey k = mTaskKeys.get(i);
-            mTaskKeyIndices.put(k, i);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index fdae917..32e62cf 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -18,8 +18,6 @@
 
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.WindowManager.DOCKED_BOTTOM;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.DOCKED_LEFT;
@@ -52,8 +50,6 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsDebugFlags;
-import com.android.systemui.recents.misc.NamedCounter;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.views.AnimationProps;
@@ -64,10 +60,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
-import java.util.Random;
 
 
 /**
@@ -75,7 +68,7 @@
  */
 interface TaskFilter {
     /** Returns whether the filter accepts the specified task */
-    public boolean acceptTask(SparseArray<Task> taskIdMap, Task t, int index);
+    boolean acceptTask(SparseArray<Task> taskIdMap, Task t, int index);
 }
 
 /**
@@ -85,7 +78,7 @@
 
     ArrayList<Task> mTasks = new ArrayList<>();
     ArrayList<Task> mFilteredTasks = new ArrayList<>();
-    ArrayMap<Task.TaskKey, Integer> mTaskIndices = new ArrayMap<>();
+    ArrayMap<Task.TaskKey, Integer> mFilteredTaskIndices = new ArrayMap<>();
     TaskFilter mFilter;
 
     /** Sets the task filter, saving the current touch state */
@@ -112,25 +105,6 @@
         updateFilteredTasks();
     }
 
-    /**
-     * Moves the given task.
-     */
-    public void setTaskWindowingMode(Task task, int insertIndex, int windowingMode) {
-        int taskIndex = indexOf(task);
-        if (taskIndex != insertIndex) {
-            mTasks.remove(taskIndex);
-            if (taskIndex < insertIndex) {
-                insertIndex--;
-            }
-            mTasks.add(insertIndex, task);
-        }
-
-        // Update the stack id now, after we've moved the task, and before we update the
-        // filtered tasks
-        task.setWindowingMode(windowingMode);
-        updateFilteredTasks();
-    }
-
     /** Sets the list of tasks */
     void set(List<Task> tasks) {
         mTasks.clear();
@@ -150,8 +124,8 @@
 
     /** Returns the index of this task in the list of filtered tasks */
     int indexOf(Task t) {
-        if (t != null && mTaskIndices.containsKey(t.key)) {
-            return mTaskIndices.get(t.key);
+        if (t != null && mFilteredTaskIndices.containsKey(t.key)) {
+            return mFilteredTaskIndices.get(t.key);
         }
         return -1;
     }
@@ -163,7 +137,7 @@
 
     /** Returns whether the filtered list contains this task */
     boolean contains(Task t) {
-        return mTaskIndices.containsKey(t.key);
+        return mFilteredTaskIndices.containsKey(t.key);
     }
 
     /** Updates the list of filtered tasks whenever the base task list changes */
@@ -193,18 +167,13 @@
     /** Updates the mapping of tasks to indices. */
     private void updateFilteredTaskIndices() {
         int taskCount = mFilteredTasks.size();
-        mTaskIndices.clear();
+        mFilteredTaskIndices.clear();
         for (int i = 0; i < taskCount; i++) {
             Task t = mFilteredTasks.get(i);
-            mTaskIndices.put(t.key, i);
+            mFilteredTaskIndices.put(t.key, i);
         }
     }
 
-    /** Returns whether this task list is filtered */
-    boolean hasFilter() {
-        return (mFilter != null);
-    }
-
     /** Returns the list of filtered tasks */
     ArrayList<Task> getTasks() {
         return mFilteredTasks;
@@ -541,45 +510,15 @@
         }
     }
 
-    // A comparator that sorts tasks by their freeform state
-    private Comparator<Task> FREEFORM_COMPARATOR = new Comparator<Task>() {
-        @Override
-        public int compare(Task o1, Task o2) {
-            if (o1.isFreeformTask() && !o2.isFreeformTask()) {
-                return 1;
-            } else if (o2.isFreeformTask() && !o1.isFreeformTask()) {
-                return -1;
-            }
-            return Long.compare(o1.temporarySortIndexInStack, o2.temporarySortIndexInStack);
-        }
-    };
-
-
-    // The task offset to apply to a task id as a group affiliation
-    static final int IndividualTaskIdOffset = 1 << 16;
-
     ArrayList<Task> mRawTaskList = new ArrayList<>();
     FilteredTaskList mStackTaskList = new FilteredTaskList();
     TaskStackCallbacks mCb;
 
-    ArrayList<TaskGrouping> mGroups = new ArrayList<>();
-    ArrayMap<Integer, TaskGrouping> mAffinitiesGroups = new ArrayMap<>();
-
     public TaskStack() {
-        // Ensure that we only show non-docked tasks
+        // Ensure that we only show stack tasks
         mStackTaskList.setFilter(new TaskFilter() {
             @Override
             public boolean acceptTask(SparseArray<Task> taskIdMap, Task t, int index) {
-                if (RecentsDebugFlags.Static.EnableAffiliatedTaskGroups) {
-                    if (t.isAffiliatedTask()) {
-                        // If this task is affiliated with another parent in the stack, then the
-                        // historical state of this task depends on the state of the parent task
-                        Task parentTask = taskIdMap.get(t.affiliationTaskId);
-                        if (parentTask != null) {
-                            t = parentTask;
-                        }
-                    }
-                }
                 return t.isStackTask;
             }
         });
@@ -590,41 +529,6 @@
         mCb = cb;
     }
 
-    /** Sets the windowing mode for a given task. */
-    public void setTaskWindowingMode(Task task, int windowingMode) {
-        // Find the index to insert into
-        ArrayList<Task> taskList = mStackTaskList.getTasks();
-        int taskCount = taskList.size();
-        if (!task.isFreeformTask() && (windowingMode == WINDOWING_MODE_FREEFORM)) {
-            // Insert freeform tasks at the front
-            mStackTaskList.setTaskWindowingMode(task, taskCount, windowingMode);
-        } else if (task.isFreeformTask() && (windowingMode == WINDOWING_MODE_FULLSCREEN)) {
-            // Insert after the first stacked task
-            int insertIndex = 0;
-            for (int i = taskCount - 1; i >= 0; i--) {
-                if (!taskList.get(i).isFreeformTask()) {
-                    insertIndex = i + 1;
-                    break;
-                }
-            }
-            mStackTaskList.setTaskWindowingMode(task, insertIndex, windowingMode);
-        }
-    }
-
-    /** Does the actual work associated with removing the task. */
-    void removeTaskImpl(FilteredTaskList taskList, Task t) {
-        // Remove the task from the list
-        taskList.remove(t);
-        // Remove it from the group as well, and if it is empty, remove the group
-        TaskGrouping group = t.group;
-        if (group != null) {
-            group.removeTask(t);
-            if (group.getTaskCount() == 0) {
-                removeGroup(group);
-            }
-        }
-    }
-
     /**
      * Removes a task from the stack, with an additional {@param animation} hint to the callbacks on
      * how they should update themselves.
@@ -640,8 +544,8 @@
     public void removeTask(Task t, AnimationProps animation, boolean fromDockGesture,
             boolean dismissRecentsIfAllRemoved) {
         if (mStackTaskList.contains(t)) {
-            removeTaskImpl(mStackTaskList, t);
-            Task newFrontMostTask = getStackFrontMostTask(false  /* includeFreeform */);
+            mStackTaskList.remove(t);
+            Task newFrontMostTask = getStackFrontMostTask();
             if (mCb != null) {
                 // Notify that a task has been removed
                 mCb.onStackTaskRemoved(this, t, newFrontMostTask, animation,
@@ -658,7 +562,7 @@
         ArrayList<Task> tasks = mStackTaskList.getTasks();
         for (int i = tasks.size() - 1; i >= 0; i--) {
             Task t = tasks.get(i);
-            removeTaskImpl(mStackTaskList, t);
+            mStackTaskList.remove(t);
             mRawTaskList.remove(t);
         }
         if (mCb != null && notifyStackChanges) {
@@ -669,10 +573,10 @@
 
 
     /**
-     * @see #setTasks(Context, List, boolean, boolean)
+     * @see #setTasks(List, boolean)
      */
-    public void setTasks(Context context, TaskStack stack, boolean notifyStackChanges) {
-        setTasks(context, stack.mRawTaskList, notifyStackChanges);
+    public void setTasks(TaskStack stack, boolean notifyStackChanges) {
+        setTasks(stack.mRawTaskList, notifyStackChanges);
     }
 
     /**
@@ -681,7 +585,7 @@
      * @param tasks the new set of tasks to replace the current set.
      * @param notifyStackChanges whether or not to callback on specific changes to the list of tasks.
      */
-    public void setTasks(Context context, List<Task> tasks, boolean notifyStackChanges) {
+    public void setTasks(List<Task> tasks, boolean notifyStackChanges) {
         // Compute a has set for each of the tasks
         ArrayMap<Task.TaskKey, Task> currentTasksMap = createTaskKeyMapFromList(mRawTaskList);
         ArrayMap<Task.TaskKey, Task> newTasksMap = createTaskKeyMapFromList(tasks);
@@ -703,7 +607,6 @@
                     removedTasks.add(task);
                 }
             }
-            task.setGroup(null);
         }
 
         // Add any new tasks
@@ -726,17 +629,13 @@
         for (int i = allTasks.size() - 1; i >= 0; i--) {
             allTasks.get(i).temporarySortIndexInStack = i;
         }
-        Collections.sort(allTasks, FREEFORM_COMPARATOR);
 
         mStackTaskList.set(allTasks);
         mRawTaskList = allTasks;
 
-        // Update the affiliated groupings
-        createAffiliatedGroupings(context);
-
         // Only callback for the removed tasks after the stack has updated
         int removedTaskCount = removedTasks.size();
-        Task newFrontMostTask = getStackFrontMostTask(false);
+        Task newFrontMostTask = getStackFrontMostTask();
         for (int i = 0; i < removedTaskCount; i++) {
             mCb.onStackTaskRemoved(this, removedTasks.get(i), newFrontMostTask,
                     AnimationProps.IMMEDIATE, false /* fromDockGesture */,
@@ -758,18 +657,12 @@
     /**
      * Gets the front-most task in the stack.
      */
-    public Task getStackFrontMostTask(boolean includeFreeformTasks) {
+    public Task getStackFrontMostTask() {
         ArrayList<Task> stackTasks = mStackTaskList.getTasks();
         if (stackTasks.isEmpty()) {
             return null;
         }
-        for (int i = stackTasks.size() - 1; i >= 0; i--) {
-            Task task = stackTasks.get(i);
-            if (!task.isFreeformTask() || includeFreeformTasks) {
-                return task;
-            }
-        }
-        return null;
+        return stackTasks.get(stackTasks.size() - 1);
     }
 
     /** Gets the task keys */
@@ -792,22 +685,6 @@
     }
 
     /**
-     * Returns the set of "freeform" tasks in the stack.
-     */
-    public ArrayList<Task> getFreeformTasks() {
-        ArrayList<Task> freeformTasks = new ArrayList<>();
-        ArrayList<Task> tasks = mStackTaskList.getTasks();
-        int taskCount = tasks.size();
-        for (int i = 0; i < taskCount; i++) {
-            Task task = tasks.get(i);
-            if (task.isFreeformTask()) {
-                freeformTasks.add(task);
-            }
-        }
-        return freeformTasks;
-    }
-
-    /**
      * Computes a set of all the active and historical tasks.
      */
     public ArrayList<Task> computeAllTasksList() {
@@ -817,7 +694,7 @@
     }
 
     /**
-     * Returns the number of stack and freeform tasks.
+     * Returns the number of stacktasks.
      */
     public int getTaskCount() {
         return mStackTaskList.size();
@@ -827,32 +704,7 @@
      * Returns the number of stack tasks.
      */
     public int getStackTaskCount() {
-        ArrayList<Task> tasks = mStackTaskList.getTasks();
-        int stackCount = 0;
-        int taskCount = tasks.size();
-        for (int i = 0; i < taskCount; i++) {
-            Task task = tasks.get(i);
-            if (!task.isFreeformTask()) {
-                stackCount++;
-            }
-        }
-        return stackCount;
-    }
-
-    /**
-     * Returns the number of freeform tasks.
-     */
-    public int getFreeformTaskCount() {
-        ArrayList<Task> tasks = mStackTaskList.getTasks();
-        int freeformCount = 0;
-        int taskCount = tasks.size();
-        for (int i = 0; i < taskCount; i++) {
-            Task task = tasks.get(i);
-            if (task.isFreeformTask()) {
-                freeformCount++;
-            }
-        }
-        return freeformCount;
+        return mStackTaskList.size();
     }
 
     /**
@@ -930,143 +782,7 @@
         }
         return null;
     }
-
-    /******** Grouping ********/
-
-    /** Adds a group to the set */
-    public void addGroup(TaskGrouping group) {
-        mGroups.add(group);
-        mAffinitiesGroups.put(group.affiliation, group);
-    }
-
-    public void removeGroup(TaskGrouping group) {
-        mGroups.remove(group);
-        mAffinitiesGroups.remove(group.affiliation);
-    }
-
-    /** Returns the group with the specified affiliation. */
-    public TaskGrouping getGroupWithAffiliation(int affiliation) {
-        return mAffinitiesGroups.get(affiliation);
-    }
-
-    /**
-     * Temporary: This method will simulate affiliation groups
-     */
-    void createAffiliatedGroupings(Context context) {
-        mGroups.clear();
-        mAffinitiesGroups.clear();
-
-        if (RecentsDebugFlags.Static.EnableMockTaskGroups) {
-            ArrayMap<Task.TaskKey, Task> taskMap = new ArrayMap<>();
-            // Sort all tasks by increasing firstActiveTime of the task
-            ArrayList<Task> tasks = mStackTaskList.getTasks();
-            Collections.sort(tasks, new Comparator<Task>() {
-                @Override
-                public int compare(Task task, Task task2) {
-                    return Long.compare(task.key.firstActiveTime, task2.key.firstActiveTime);
-                }
-            });
-            // Create groups when sequential packages are the same
-            NamedCounter counter = new NamedCounter("task-group", "");
-            int taskCount = tasks.size();
-            String prevPackage = "";
-            int prevAffiliation = -1;
-            Random r = new Random();
-            int groupCountDown = RecentsDebugFlags.Static.MockTaskGroupsTaskCount;
-            for (int i = 0; i < taskCount; i++) {
-                Task t = tasks.get(i);
-                String packageName = t.key.getComponent().getPackageName();
-                packageName = "pkg";
-                TaskGrouping group;
-                if (packageName.equals(prevPackage) && groupCountDown > 0) {
-                    group = getGroupWithAffiliation(prevAffiliation);
-                    groupCountDown--;
-                } else {
-                    int affiliation = IndividualTaskIdOffset + t.key.id;
-                    group = new TaskGrouping(affiliation);
-                    addGroup(group);
-                    prevAffiliation = affiliation;
-                    prevPackage = packageName;
-                    groupCountDown = RecentsDebugFlags.Static.MockTaskGroupsTaskCount;
-                }
-                group.addTask(t);
-                taskMap.put(t.key, t);
-            }
-            // Sort groups by increasing latestActiveTime of the group
-            Collections.sort(mGroups, new Comparator<TaskGrouping>() {
-                @Override
-                public int compare(TaskGrouping taskGrouping, TaskGrouping taskGrouping2) {
-                    return Long.compare(taskGrouping.latestActiveTimeInGroup,
-                            taskGrouping2.latestActiveTimeInGroup);
-                }
-            });
-            // Sort group tasks by increasing firstActiveTime of the task, and also build a new list
-            // of tasks
-            int taskIndex = 0;
-            int groupCount = mGroups.size();
-            for (int i = 0; i < groupCount; i++) {
-                TaskGrouping group = mGroups.get(i);
-                Collections.sort(group.mTaskKeys, new Comparator<Task.TaskKey>() {
-                    @Override
-                    public int compare(Task.TaskKey taskKey, Task.TaskKey taskKey2) {
-                        return Long.compare(taskKey.firstActiveTime, taskKey2.firstActiveTime);
-                    }
-                });
-                ArrayList<Task.TaskKey> groupTasks = group.mTaskKeys;
-                int groupTaskCount = groupTasks.size();
-                for (int j = 0; j < groupTaskCount; j++) {
-                    tasks.set(taskIndex, taskMap.get(groupTasks.get(j)));
-                    taskIndex++;
-                }
-            }
-            mStackTaskList.set(tasks);
-        } else {
-            // Create the task groups
-            ArrayMap<Task.TaskKey, Task> tasksMap = new ArrayMap<>();
-            ArrayList<Task> tasks = mStackTaskList.getTasks();
-            int taskCount = tasks.size();
-            for (int i = 0; i < taskCount; i++) {
-                Task t = tasks.get(i);
-                TaskGrouping group;
-                if (RecentsDebugFlags.Static.EnableAffiliatedTaskGroups) {
-                    int affiliation = t.affiliationTaskId > 0 ? t.affiliationTaskId :
-                            IndividualTaskIdOffset + t.key.id;
-                    if (mAffinitiesGroups.containsKey(affiliation)) {
-                        group = getGroupWithAffiliation(affiliation);
-                    } else {
-                        group = new TaskGrouping(affiliation);
-                        addGroup(group);
-                    }
-                } else {
-                    group = new TaskGrouping(t.key.id);
-                    addGroup(group);
-                }
-                group.addTask(t);
-                tasksMap.put(t.key, t);
-            }
-            // Update the task colors for each of the groups
-            float minAlpha = context.getResources().getFloat(
-                    R.dimen.recents_task_affiliation_color_min_alpha_percentage);
-            int taskGroupCount = mGroups.size();
-            for (int i = 0; i < taskGroupCount; i++) {
-                TaskGrouping group = mGroups.get(i);
-                taskCount = group.getTaskCount();
-                // Ignore the groups that only have one task
-                if (taskCount <= 1) continue;
-                // Calculate the group color distribution
-                int affiliationColor = tasksMap.get(group.mTaskKeys.get(0)).affiliationColor;
-                float alphaStep = (1f - minAlpha) / taskCount;
-                float alpha = 1f;
-                for (int j = 0; j < taskCount; j++) {
-                    Task t = tasksMap.get(group.mTaskKeys.get(j));
-                    t.colorPrimary = Utilities.getColorWithOverlay(affiliationColor, Color.WHITE,
-                            alpha);
-                    alpha -= alphaStep;
-                }
-            }
-        }
-    }
-
+    
     /**
      * Computes the components of tasks in this stack that have been removed as a result of a change
      * in the specified package.
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
deleted file mode 100644
index 035c058..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.content.Context;
-import android.graphics.RectF;
-import android.util.ArrayMap;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.model.Task;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * The layout logic for the contents of the freeform workspace.
- */
-public class FreeformWorkspaceLayoutAlgorithm {
-
-    // Optimization, allows for quick lookup of task -> rect
-    private ArrayMap<Task.TaskKey, RectF> mTaskRectMap = new ArrayMap<>();
-
-    private int mTaskPadding;
-
-    public FreeformWorkspaceLayoutAlgorithm(Context context) {
-        reloadOnConfigurationChange(context);
-    }
-
-    /**
-     * Reloads the layout for the current configuration.
-     */
-    public void reloadOnConfigurationChange(Context context) {
-        // This is applied to the edges of each task
-        mTaskPadding = context.getResources().getDimensionPixelSize(
-                R.dimen.recents_freeform_layout_task_padding) / 2;
-    }
-
-    /**
-     * Updates the layout for each of the freeform workspace tasks.  This is called after the stack
-     * layout is updated.
-     */
-    public void update(List<Task> freeformTasks, TaskStackLayoutAlgorithm stackLayout) {
-        Collections.reverse(freeformTasks);
-        mTaskRectMap.clear();
-
-        int numFreeformTasks = stackLayout.mNumFreeformTasks;
-        if (!freeformTasks.isEmpty()) {
-
-            // Normalize the widths so that we can calculate the best layout below
-            int workspaceWidth = stackLayout.mFreeformRect.width();
-            int workspaceHeight = stackLayout.mFreeformRect.height();
-            float normalizedWorkspaceWidth = (float) workspaceWidth / workspaceHeight;
-            float normalizedWorkspaceHeight = 1f;
-            float[] normalizedTaskWidths = new float[numFreeformTasks];
-            for (int i = 0; i < numFreeformTasks; i++) {
-                Task task = freeformTasks.get(i);
-                float rowTaskWidth;
-                if (task.bounds != null) {
-                    rowTaskWidth = (float) task.bounds.width() / task.bounds.height();
-                } else {
-                    // If this is a stack task that was dragged into the freeform workspace, then
-                    // the task will not yet have an associated bounds, so assume the full workspace
-                    // width for the time being
-                    rowTaskWidth = normalizedWorkspaceWidth;
-                }
-                // Bound the task width to the workspace width so that at the worst case, it will
-                // fit its own row
-                normalizedTaskWidths[i] = Math.min(rowTaskWidth, normalizedWorkspaceWidth);
-            }
-
-            // Determine the scale to best fit each of the tasks in the workspace
-            float rowScale = 0.85f;
-            float rowWidth = 0f;
-            float maxRowWidth = 0f;
-            int rowCount = 1;
-            for (int i = 0; i < numFreeformTasks;) {
-                float width = normalizedTaskWidths[i] * rowScale;
-                if (rowWidth + width > normalizedWorkspaceWidth) {
-                    // That is too long for this row, create new row
-                    if ((rowCount + 1) * rowScale > normalizedWorkspaceHeight) {
-                        // The new row is too high, so we need to try fitting again.  Update the
-                        // scale to be the smaller of the scale needed to fit the task in the
-                        // previous row, or the scale needed to fit the new row
-                        rowScale = Math.min(normalizedWorkspaceWidth / (rowWidth + width),
-                                normalizedWorkspaceHeight / (rowCount + 1));
-                        rowCount = 1;
-                        rowWidth = 0;
-                        i = 0;
-                    } else {
-                        // The new row fits, so continue
-                        rowWidth = width;
-                        rowCount++;
-                        i++;
-                    }
-                } else {
-                    // Task is OK in this row
-                    rowWidth += width;
-                    i++;
-                }
-                maxRowWidth = Math.max(rowWidth, maxRowWidth);
-            }
-
-            // Normalize each of the actual rects to that scale
-            float defaultRowLeft = ((1f - (maxRowWidth / normalizedWorkspaceWidth)) *
-                    workspaceWidth) / 2f;
-            float rowLeft = defaultRowLeft;
-            float rowTop = ((1f - (rowScale * rowCount)) * workspaceHeight) / 2f;
-            float rowHeight = rowScale * workspaceHeight;
-            for (int i = 0; i < numFreeformTasks; i++) {
-                Task task = freeformTasks.get(i);
-                float width = rowHeight * normalizedTaskWidths[i];
-                if (rowLeft + width > workspaceWidth) {
-                    // This goes on the next line
-                    rowTop += rowHeight;
-                    rowLeft = defaultRowLeft;
-                }
-                RectF rect = new RectF(rowLeft, rowTop, rowLeft + width, rowTop + rowHeight);
-                rect.inset(mTaskPadding, mTaskPadding);
-                rowLeft += width;
-                mTaskRectMap.put(task.key, rect);
-            }
-        }
-    }
-
-    /**
-     * Returns whether the transform is available for the given task.
-     */
-    public boolean isTransformAvailable(Task task, TaskStackLayoutAlgorithm stackLayout) {
-        if (stackLayout.mNumFreeformTasks == 0 || task == null) {
-            return false;
-        }
-        return mTaskRectMap.containsKey(task.key);
-    }
-
-    /**
-     * Returns the transform for the given task.  Any rect returned will be offset by the actual
-     * transform for the freeform workspace.
-     */
-    public TaskViewTransform getTransform(Task task, TaskViewTransform transformOut,
-            TaskStackLayoutAlgorithm stackLayout) {
-        if (mTaskRectMap.containsKey(task.key)) {
-            final RectF ffRect = mTaskRectMap.get(task.key);
-
-            transformOut.scale = 1f;
-            transformOut.alpha = 1f;
-            transformOut.translationZ = stackLayout.mMaxTranslationZ;
-            transformOut.dimAlpha = 0f;
-            transformOut.viewOutlineAlpha = TaskStackLayoutAlgorithm.OUTLINE_ALPHA_MAX_VALUE;
-            transformOut.rect.set(ffRect);
-            transformOut.rect.offset(stackLayout.mFreeformRect.left, stackLayout.mFreeformRect.top);
-            transformOut.visible = true;
-            return transformOut;
-        }
-        return null;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index ee05d81..baa5e62 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -19,7 +19,6 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
@@ -188,20 +187,9 @@
         } else {
             LaunchTaskStartedEvent launchStartedEvent = new LaunchTaskStartedEvent(taskView,
                     screenPinningRequested);
-            if (task.group != null && !task.group.isFrontMostTask(task)) {
-                launchStartedEvent.addPostAnimationCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        startTaskActivity(stack, task, taskView, opts, transitionFuture,
-                                windowingMode, activityType);
-                    }
-                });
-                EventBus.getDefault().send(launchStartedEvent);
-            } else {
-                EventBus.getDefault().send(launchStartedEvent);
-                startTaskActivity(stack, task, taskView, opts, transitionFuture,
-                        windowingMode, activityType);
-            }
+            EventBus.getDefault().send(launchStartedEvent);
+            startTaskActivity(stack, task, taskView, opts, transitionFuture, windowingMode,
+                    activityType);
         }
         Recents.getSystemServices().sendCloseSystemWindows(
                 StatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
@@ -329,7 +317,6 @@
 
         // If this is a full screen stack, the transition will be towards the single, full screen
         // task. We only need the transition spec for this task.
-        List<AppTransitionAnimationSpec> specs = new ArrayList<>();
 
         // TODO: Sometimes targetStackId is not initialized after reboot, so we also have to
         // check for INVALID_STACK_ID (now WINDOWING_MODE_UNDEFINED)
@@ -338,6 +325,7 @@
                 || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
                 || activityType == ACTIVITY_TYPE_ASSISTANT
                 || windowingMode == WINDOWING_MODE_UNDEFINED) {
+            List<AppTransitionAnimationSpec> specs = new ArrayList<>();
             if (taskView == null) {
                 specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect));
             } else {
@@ -351,34 +339,7 @@
             }
             return specs;
         }
-
-        // Otherwise, for freeform tasks, create a new animation spec for each task we have to
-        // launch
-        TaskStack stack = stackView.getStack();
-        ArrayList<Task> tasks = stack.getStackTasks();
-        int taskCount = tasks.size();
-        for (int i = taskCount - 1; i >= 0; i--) {
-            Task t = tasks.get(i);
-            if (t.isFreeformTask() || windowingMode == WINDOWING_MODE_FREEFORM) {
-                TaskView tv = stackView.getChildViewForTask(t);
-                if (tv == null) {
-                    // TODO: Create a different animation task rect for this case (though it should
-                    //       never happen)
-                    specs.add(composeOffscreenAnimationSpec(t, offscreenTaskRect));
-                } else {
-                    mTmpTransform.fillIn(taskView);
-                    stackLayout.transformToScreenCoordinates(mTmpTransform,
-                            null /* windowOverrideRect */);
-                    AppTransitionAnimationSpec spec = composeAnimationSpec(stackView, tv,
-                            mTmpTransform, true /* addHeaderBitmap */);
-                    if (spec != null) {
-                        specs.add(spec);
-                    }
-                }
-            }
-        }
-
-        return specs;
+        return Collections.emptyList();
     }
 
     /**
@@ -462,7 +423,7 @@
         // force the task thumbnail to full stackView height immediately causing the transition
         // jarring.
         if (!Recents.getConfiguration().isLowRamDevice && taskView.getTask() !=
-                stackView.getStack().getStackFrontMostTask(false /* includeFreeformTasks */)) {
+                stackView.getStack().getStackFrontMostTask()) {
             taskRect.bottom = taskRect.top + stackView.getMeasuredHeight();
         }
         return new AppTransitionAnimationSpec(taskView.getTask().key.id, b, taskRect);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index c7edb9a..e1b22b4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -16,10 +16,6 @@
 
 package com.android.systemui.recents.views;
 
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.ActivityOptions.OnAnimationStartedListener;
@@ -114,7 +110,6 @@
     private final int mStackButtonShadowColor;
 
     private boolean mAwaitingFirstLayout = true;
-    private boolean mLastTaskLaunchedWasFreeform;
 
     @ViewDebug.ExportedProperty(category="recents")
     Rect mSystemInsets = new Rect();
@@ -165,22 +160,20 @@
         mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false);
         addView(mEmptyView);
 
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            if (mStackActionButton != null) {
-                removeView(mStackActionButton);
-            }
-            mStackActionButton = (TextView) inflater.inflate(Recents.getConfiguration()
-                            .isLowRamDevice
-                        ? R.layout.recents_low_ram_stack_action_button
-                        : R.layout.recents_stack_action_button,
-                    this, false);
-
-            mStackButtonShadowRadius = mStackActionButton.getShadowRadius();
-            mStackButtonShadowDistance = new PointF(mStackActionButton.getShadowDx(),
-                    mStackActionButton.getShadowDy());
-            mStackButtonShadowColor = mStackActionButton.getShadowColor();
-            addView(mStackActionButton);
+        if (mStackActionButton != null) {
+            removeView(mStackActionButton);
         }
+        mStackActionButton = (TextView) inflater.inflate(Recents.getConfiguration()
+                        .isLowRamDevice
+                    ? R.layout.recents_low_ram_stack_action_button
+                    : R.layout.recents_stack_action_button,
+                this, false);
+
+        mStackButtonShadowRadius = mStackActionButton.getShadowRadius();
+        mStackButtonShadowDistance = new PointF(mStackActionButton.getShadowDx(),
+                mStackActionButton.getShadowDy());
+        mStackButtonShadowColor = mStackActionButton.getShadowColor();
+        addView(mStackActionButton);
 
         reevaluateStyles();
     }
@@ -232,7 +225,6 @@
 
         // Reset the state
         mAwaitingFirstLayout = !isResumingFromVisible;
-        mLastTaskLaunchedWasFreeform = false;
 
         // Update the stack
         mTaskStackView.onReload(isResumingFromVisible);
@@ -319,13 +311,6 @@
         }
     }
 
-    /**
-     * Returns whether the last task launched was in the freeform stack or not.
-     */
-    public boolean isLastTaskLaunchedFreeform() {
-        return mLastTaskLaunchedWasFreeform;
-    }
-
     /** Launches the focused task from the first stack if possible */
     public boolean launchFocusedTask(int logEvent) {
         if (mTaskStackView != null) {
@@ -371,9 +356,7 @@
         mEmptyView.setText(msgResId);
         mEmptyView.setVisibility(View.VISIBLE);
         mEmptyView.bringToFront();
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            mStackActionButton.bringToFront();
-        }
+        mStackActionButton.bringToFront();
     }
 
     /**
@@ -383,9 +366,7 @@
         mEmptyView.setVisibility(View.INVISIBLE);
         mTaskStackView.setVisibility(View.VISIBLE);
         mTaskStackView.bringToFront();
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            mStackActionButton.bringToFront();
-        }
+        mStackActionButton.bringToFront();
     }
 
     /**
@@ -433,13 +414,11 @@
                     MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
         }
 
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            // Measure the stack action button within the constraints of the space above the stack
-            Rect buttonBounds = mTaskStackView.mLayoutAlgorithm.getStackActionButtonRect();
-            measureChild(mStackActionButton,
-                    MeasureSpec.makeMeasureSpec(buttonBounds.width(), MeasureSpec.AT_MOST),
-                    MeasureSpec.makeMeasureSpec(buttonBounds.height(), MeasureSpec.AT_MOST));
-        }
+        // Measure the stack action button within the constraints of the space above the stack
+        Rect buttonBounds = mTaskStackView.mLayoutAlgorithm.getStackActionButtonRect();
+        measureChild(mStackActionButton,
+                MeasureSpec.makeMeasureSpec(buttonBounds.width(), MeasureSpec.AT_MOST),
+                MeasureSpec.makeMeasureSpec(buttonBounds.height(), MeasureSpec.AT_MOST));
 
         setMeasuredDimension(width, height);
     }
@@ -473,13 +452,11 @@
         mBackgroundScrim.setBounds(left, top, right, bottom);
         mMultiWindowBackgroundScrim.setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y);
 
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            // Layout the stack action button such that its drawable is start-aligned with the
-            // stack, vertically centered in the available space above the stack
-            Rect buttonBounds = getStackActionButtonBoundsFromStackLayout();
-            mStackActionButton.layout(buttonBounds.left, buttonBounds.top, buttonBounds.right,
-                    buttonBounds.bottom);
-        }
+        // Layout the stack action button such that its drawable is start-aligned with the
+        // stack, vertically centered in the available space above the stack
+        Rect buttonBounds = getStackActionButtonBoundsFromStackLayout();
+        mStackActionButton.layout(buttonBounds.left, buttonBounds.top, buttonBounds.right,
+                buttonBounds.bottom);
 
         if (mAwaitingFirstLayout) {
             mAwaitingFirstLayout = false;
@@ -542,7 +519,6 @@
     /**** EventBus Events ****/
 
     public final void onBusEvent(LaunchTaskEvent event) {
-        mLastTaskLaunchedWasFreeform = event.task.isFreeformTask();
         mTransitionHelper.launchTaskFromRecents(getStack(), event.task, mTaskStackView,
                 event.taskView, event.screenPinningRequested, event.targetWindowingMode,
                 event.targetActivityType);
@@ -553,10 +529,8 @@
 
     public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
         int taskViewExitToHomeDuration = TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION;
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            // Hide the stack action button
-            EventBus.getDefault().send(new HideStackActionButtonEvent());
-        }
+        // Hide the stack action button
+        EventBus.getDefault().send(new HideStackActionButtonEvent());
         animateBackgroundScrim(0f, taskViewExitToHomeDuration);
 
         if (Recents.getConfiguration().isLowRamDevice) {
@@ -731,18 +705,10 @@
     }
 
     public final void onBusEvent(ShowStackActionButtonEvent event) {
-        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
-            return;
-        }
-
         showStackActionButton(SHOW_STACK_ACTION_BUTTON_DURATION, event.translate);
     }
 
     public final void onBusEvent(HideStackActionButtonEvent event) {
-        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
-            return;
-        }
-
         hideStackActionButton(HIDE_STACK_ACTION_BUTTON_DURATION, true /* translate */);
     }
 
@@ -758,10 +724,6 @@
      * Shows the stack action button.
      */
     private void showStackActionButton(final int duration, final boolean translate) {
-        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
-            return;
-        }
-
         final ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
         if (mStackActionButton.getVisibility() == View.INVISIBLE) {
             mStackActionButton.setVisibility(View.VISIBLE);
@@ -794,10 +756,6 @@
      * Hides the stack action button.
      */
     private void hideStackActionButton(int duration, boolean translate) {
-        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
-            return;
-        }
-
         final ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
         hideStackActionButton(duration, translate, postAnimationTrigger);
         postAnimationTrigger.flushLastDecrementRunnables();
@@ -808,10 +766,6 @@
      */
     private void hideStackActionButton(int duration, boolean translate,
                                        final ReferenceCountedTrigger postAnimationTrigger) {
-        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
-            return;
-        }
-
         if (mStackActionButton.getVisibility() == View.VISIBLE) {
             if (translate) {
                 mStackActionButton.animate().translationY(mStackActionButton.getMeasuredHeight()
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index 81bf6af..f47c1d2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -161,20 +161,12 @@
         for (int i = taskViews.size() - 1; i >= 0; i--) {
             TaskView tv = taskViews.get(i);
             Task task = tv.getTask();
-            boolean currentTaskOccludesLaunchTarget = launchTargetTask != null &&
-                    launchTargetTask.group != null &&
-                    launchTargetTask.group.isTaskAboveTask(task, launchTargetTask);
-            boolean hideTask = launchTargetTask != null &&
-                    launchTargetTask.isFreeformTask() &&
-                    task.isFreeformTask();
 
             // Get the current transform for the task, which will be used to position it offscreen
             stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
                     null);
 
-            if (hideTask) {
-                tv.setVisibility(View.INVISIBLE);
-            } else if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
+            if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
                 if (task.isLaunchTarget) {
                     tv.onPrepareLaunchTargetForEnterAnimation();
                 } else if (isLowRamDevice && i >= taskViews.size() -
@@ -195,13 +187,6 @@
                     // com.android.server.wm.AppTransition#DEFAULT_APP_TRANSITION_DURATION}
                     mStackView.updateTaskViewToTransform(tv, mTmpTransform,
                             new AnimationProps(336, Interpolators.FAST_OUT_SLOW_IN));
-                } else if (currentTaskOccludesLaunchTarget) {
-                    // Move the task view slightly lower so we can animate it in
-                    mTmpTransform.rect.offset(0, taskViewAffiliateGroupEnterOffset);
-                    mTmpTransform.alpha = 0f;
-                    mStackView.updateTaskViewToTransform(tv, mTmpTransform,
-                            AnimationProps.IMMEDIATE);
-                    tv.setClipViewInStack(false);
                 }
             } else if (launchState.launchedFromHome) {
                 if (isLowRamDevice) {
@@ -266,9 +251,6 @@
             int taskIndexFromBack = i;
             final TaskView tv = taskViews.get(i);
             Task task = tv.getTask();
-            boolean currentTaskOccludesLaunchTarget = launchTargetTask != null &&
-                    launchTargetTask.group != null &&
-                    launchTargetTask.group.isTaskAboveTask(task, launchTargetTask);
 
             // Get the current transform for the task, which will be updated to the final transform
             // to animate to depending on how recents was invoked
@@ -280,21 +262,6 @@
                     tv.onStartLaunchTargetEnterAnimation(mTmpTransform,
                             taskViewEnterFromAppDuration, mStackView.mScreenPinningEnabled,
                             postAnimationTrigger);
-                } else {
-                    // Animate the task up if it was occluding the launch target
-                    if (currentTaskOccludesLaunchTarget) {
-                        AnimationProps taskAnimation = new AnimationProps(
-                                taskViewEnterFromAffiliatedAppDuration, Interpolators.ALPHA_IN,
-                                new AnimatorListenerAdapter() {
-                                    @Override
-                                    public void onAnimationEnd(Animator animation) {
-                                        postAnimationTrigger.decrement();
-                                        tv.setClipViewInStack(true);
-                                    }
-                                });
-                        postAnimationTrigger.increment();
-                        mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
-                    }
                 }
 
             } else if (launchState.launchedFromHome) {
@@ -423,9 +390,6 @@
         for (int i = 0; i < taskViewCount; i++) {
             TaskView tv = taskViews.get(i);
             Task task = tv.getTask();
-            boolean currentTaskOccludesLaunchTarget = launchingTask != null &&
-                    launchingTask.group != null &&
-                    launchingTask.group.isTaskAboveTask(task, launchingTask);
 
             if (tv == launchingTaskView) {
                 tv.setClipViewInStack(false);
@@ -437,17 +401,6 @@
                 });
                 tv.onStartLaunchTargetLaunchAnimation(taskViewExitToAppDuration,
                         screenPinningRequested, postAnimationTrigger);
-            } else if (currentTaskOccludesLaunchTarget) {
-                // Animate this task out of view
-                AnimationProps taskAnimation = new AnimationProps(
-                        taskViewExitToAppDuration, Interpolators.ALPHA_OUT,
-                        postAnimationTrigger.decrementOnAnimationEnd());
-                postAnimationTrigger.increment();
-
-                mTmpTransform.fillIn(tv);
-                mTmpTransform.alpha = 0f;
-                mTmpTransform.rect.offset(0, taskViewAffiliateGroupEnterOffset);
-                mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
             }
         }
     }
@@ -611,7 +564,7 @@
                 false /* ignoreTaskOverrides */, mTmpFinalTaskTransforms);
 
         // Hide the front most task view until the scroll is complete
-        Task frontMostTask = newStack.getStackFrontMostTask(false /* includeFreeform */);
+        Task frontMostTask = newStack.getStackFrontMostTask();
         final TaskView frontMostTaskView = mStackView.getChildViewForTask(frontMostTask);
         final TaskViewTransform frontMostTransform = mTmpFinalTaskTransforms.get(
                 stackTasks.indexOf(frontMostTask));
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index eaa32ee..5ba5f44 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -147,75 +147,6 @@
     }
 
     /**
-     * The various stack/freeform states.
-     */
-    public static class StackState {
-
-        public static final StackState FREEFORM_ONLY = new StackState(1f, 255);
-        public static final StackState STACK_ONLY = new StackState(0f, 0);
-        public static final StackState SPLIT = new StackState(0.5f, 255);
-
-        public final float freeformHeightPct;
-        public final int freeformBackgroundAlpha;
-
-        /**
-         * @param freeformHeightPct the percentage of the stack height (not including paddings) to
-         *                          allocate to the freeform workspace
-         * @param freeformBackgroundAlpha the background alpha for the freeform workspace
-         */
-        private StackState(float freeformHeightPct, int freeformBackgroundAlpha) {
-            this.freeformHeightPct = freeformHeightPct;
-            this.freeformBackgroundAlpha = freeformBackgroundAlpha;
-        }
-
-        /**
-         * Resolves the stack state for the layout given a task stack.
-         */
-        public static StackState getStackStateForStack(TaskStack stack) {
-            SystemServicesProxy ssp = Recents.getSystemServices();
-            boolean hasFreeformWorkspaces = ssp.hasFreeformWorkspaceSupport();
-            int freeformCount = stack.getFreeformTaskCount();
-            int stackCount = stack.getStackTaskCount();
-            if (hasFreeformWorkspaces && stackCount > 0 && freeformCount > 0) {
-                return SPLIT;
-            } else if (hasFreeformWorkspaces && freeformCount > 0) {
-                return FREEFORM_ONLY;
-            } else {
-                return STACK_ONLY;
-            }
-        }
-
-        /**
-         * Computes the freeform and stack rect for this state.
-         *
-         * @param freeformRectOut the freeform rect to be written out
-         * @param stackRectOut the stack rect, we only write out the top of the stack
-         * @param taskStackBounds the full rect that the freeform rect can take up
-         */
-        public void computeRects(Rect freeformRectOut, Rect stackRectOut,
-                Rect taskStackBounds, int topMargin, int freeformGap, int stackBottomOffset) {
-            // The freeform height is the visible height (not including system insets) - padding
-            // above freeform and below stack - gap between the freeform and stack
-            int availableHeight = taskStackBounds.height() - topMargin - stackBottomOffset;
-            int ffPaddedHeight = (int) (availableHeight * freeformHeightPct);
-            int ffHeight = Math.max(0, ffPaddedHeight - freeformGap);
-            freeformRectOut.set(taskStackBounds.left,
-                    taskStackBounds.top + topMargin,
-                    taskStackBounds.right,
-                    taskStackBounds.top + topMargin + ffHeight);
-            stackRectOut.set(taskStackBounds.left,
-                    taskStackBounds.top,
-                    taskStackBounds.right,
-                    taskStackBounds.bottom);
-            if (ffPaddedHeight > 0) {
-                stackRectOut.top += ffPaddedHeight;
-            } else {
-                stackRectOut.top += topMargin;
-            }
-        }
-    }
-
-    /**
      * @return True if we should use the grid layout.
      */
     boolean useGridLayout() {
@@ -234,15 +165,11 @@
     }
 
     Context mContext;
-    private StackState mState = StackState.SPLIT;
     private TaskStackLayoutAlgorithmCallbacks mCb;
 
     // The task bounds (untransformed) for layout.  This rect is anchored at mTaskRoot.
     @ViewDebug.ExportedProperty(category="recents")
     public Rect mTaskRect = new Rect();
-    // The freeform workspace bounds, inset by the top system insets and is a fixed height
-    @ViewDebug.ExportedProperty(category="recents")
-    public Rect mFreeformRect = new Rect();
     // The stack bounds, inset from the top system insets, and runs to the bottom of the screen
     @ViewDebug.ExportedProperty(category="recents")
     public Rect mStackRect = new Rect();
@@ -268,10 +195,6 @@
     private int mBaseBottomMargin;
     private int mMinMargin;
 
-    // The gap between the freeform and stack layouts
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mFreeformStackGap;
-
     // The initial offset that the focused task is from the top
     @ViewDebug.ExportedProperty(category="recents")
     private int mInitialTopOffset;
@@ -331,8 +254,6 @@
     // The last computed task counts
     @ViewDebug.ExportedProperty(category="recents")
     int mNumStackTasks;
-    @ViewDebug.ExportedProperty(category="recents")
-    int mNumFreeformTasks;
 
     // The min/max z translations
     @ViewDebug.ExportedProperty(category="recents")
@@ -344,8 +265,6 @@
     private SparseIntArray mTaskIndexMap = new SparseIntArray();
     private SparseArray<Float> mTaskIndexOverrideMap = new SparseArray<>();
 
-    // The freeform workspace layout
-    FreeformWorkspaceLayoutAlgorithm mFreeformLayoutAlgorithm;
     TaskGridLayoutAlgorithm mTaskGridLayoutAlgorithm;
     TaskStackLowRamLayoutAlgorithm mTaskStackLowRamLayoutAlgorithm;
 
@@ -356,7 +275,6 @@
     public TaskStackLayoutAlgorithm(Context context, TaskStackLayoutAlgorithmCallbacks cb) {
         mContext = context;
         mCb = cb;
-        mFreeformLayoutAlgorithm = new FreeformWorkspaceLayoutAlgorithm(context);
         mTaskGridLayoutAlgorithm = new TaskGridLayoutAlgorithm(context);
         mTaskStackLowRamLayoutAlgorithm = new TaskStackLowRamLayoutAlgorithm(context);
         reloadOnConfigurationChange(context);
@@ -393,7 +311,6 @@
                 R.dimen.recents_layout_initial_bottom_offset_tablet,
                 R.dimen.recents_layout_initial_bottom_offset_tablet,
                 R.dimen.recents_layout_initial_bottom_offset_tablet);
-        mFreeformLayoutAlgorithm.reloadOnConfigurationChange(context);
         mTaskGridLayoutAlgorithm.reloadOnConfigurationChange(context);
         mTaskStackLowRamLayoutAlgorithm.reloadOnConfigurationChange(context);
         mMinMargin = res.getDimensionPixelSize(R.dimen.recents_layout_min_margin);
@@ -408,8 +325,6 @@
                 R.dimen.recents_layout_side_margin_tablet_xlarge,
                 R.dimen.recents_layout_side_margin_tablet);
         mBaseBottomMargin = res.getDimensionPixelSize(R.dimen.recents_layout_bottom_margin);
-        mFreeformStackGap =
-                res.getDimensionPixelSize(R.dimen.recents_freeform_layout_bottom_margin);
         mTitleBarHeight = getDimensionForDevice(mContext,
                 R.dimen.recents_task_view_header_height,
                 R.dimen.recents_task_view_header_height,
@@ -462,8 +377,7 @@
      * Computes the stack and task rects.  The given task stack bounds already has the top/right
      * insets and left/right padding already applied.
      */
-    public void initialize(Rect displayRect, Rect windowRect, Rect taskStackBounds,
-            StackState state) {
+    public void initialize(Rect displayRect, Rect windowRect, Rect taskStackBounds) {
         Rect lastStackRect = new Rect(mStackRect);
 
         int topMargin = getScaleForExtent(windowRect, displayRect, mBaseTopMargin, mMinMargin, HEIGHT);
@@ -474,10 +388,9 @@
         mInitialBottomOffset = mBaseInitialBottomOffset;
 
         // Compute the stack bounds
-        mState = state;
         mStackBottomOffset = mSystemInsets.bottom + bottomMargin;
-        state.computeRects(mFreeformRect, mStackRect, taskStackBounds, topMargin,
-                mFreeformStackGap, mStackBottomOffset);
+        mStackRect.set(taskStackBounds);
+        mStackRect.top += topMargin;
 
         // The stack action button will take the full un-padded header space above the stack
         mStackActionButtonRect.set(mStackRect.left, mStackRect.top - topMargin,
@@ -530,26 +443,20 @@
         if (tasks.isEmpty()) {
             mFrontMostTaskP = 0;
             mMinScrollP = mMaxScrollP = mInitialScrollP = 0;
-            mNumStackTasks = mNumFreeformTasks = 0;
+            mNumStackTasks = 0;
             return;
         }
 
-        // Filter the set of freeform and stack tasks
-        ArrayList<Task> freeformTasks = new ArrayList<>();
+        // Filter the set of stack tasks
         ArrayList<Task> stackTasks = new ArrayList<>();
         for (int i = 0; i < tasks.size(); i++) {
             Task task = tasks.get(i);
             if (ignoreTasksSet.contains(task.key)) {
                 continue;
             }
-            if (task.isFreeformTask()) {
-                freeformTasks.add(task);
-            } else {
-                stackTasks.add(task);
-            }
+            stackTasks.add(task);
         }
         mNumStackTasks = stackTasks.size();
-        mNumFreeformTasks = freeformTasks.size();
 
         // Put each of the tasks in the progress map at a fixed index (does not need to actually
         // map to a scroll position, just by index)
@@ -559,11 +466,6 @@
             mTaskIndexMap.put(task.key.id, i);
         }
 
-        // Update the freeform tasks
-        if (!freeformTasks.isEmpty()) {
-            mFreeformLayoutAlgorithm.update(freeformTasks, this);
-        }
-
         // Calculate the min/max/initial scroll
         Task launchTask = stack.getLaunchTarget();
         int launchTaskIndex = launchTask != null
@@ -582,7 +484,7 @@
             } else {
                 mInitialScrollP = Utilities.clamp(launchTaskIndex - 1, mMinScrollP, mMaxScrollP);
             }
-        } else if (!ssp.hasFreeformWorkspaceSupport() && mNumStackTasks == 1) {
+        } else if (mNumStackTasks == 1) {
             // If there is one stack task, ignore the min/max/initial scroll positions
             mMinScrollP = 0;
             mMaxScrollP = 0;
@@ -767,7 +669,7 @@
     public int getInitialFocusState() {
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
         RecentsDebugFlags debugFlags = Recents.getDebugFlags();
-        if (debugFlags.isPagingEnabled() || launchState.launchedWithAltTab) {
+        if (launchState.launchedWithAltTab) {
             return STATE_FOCUSED;
         } else {
             return STATE_UNFOCUSED;
@@ -794,13 +696,6 @@
     }
 
     /**
-     * Returns the current stack state.
-     */
-    public StackState getStackState() {
-        return mState;
-    }
-
-    /**
      * Returns whether this stack layout has been initialized.
      */
     public boolean isInitialized() {
@@ -825,62 +720,44 @@
             return new VisibilityReport(1, 1);
         }
 
-        // Quick return when there are no stack tasks
-        if (mNumStackTasks == 0) {
-            return new VisibilityReport(mNumFreeformTasks > 0 ? Math.max(mNumFreeformTasks, 1) : 0,
-                    mNumFreeformTasks > 0 ? Math.max(mNumFreeformTasks, 1) : 0);
-        }
-
         // Otherwise, walk backwards in the stack and count the number of tasks and visible
-        // thumbnails and add that to the total freeform task count
+        // thumbnails and add that to the total task count
         TaskViewTransform tmpTransform = new TaskViewTransform();
         Range currentRange = getInitialFocusState() > 0f ? mFocusedRange : mUnfocusedRange;
         currentRange.offset(mInitialScrollP);
         int taskBarHeight = mContext.getResources().getDimensionPixelSize(
                 R.dimen.recents_task_view_header_height);
-        int numVisibleTasks = mNumFreeformTasks > 0 ? Math.max(mNumFreeformTasks, 1) : 0;
-        int numVisibleThumbnails = mNumFreeformTasks > 0 ? Math.max(mNumFreeformTasks, 0) : 0;
+        int numVisibleTasks = 0;
+        int numVisibleThumbnails = 0;
         float prevScreenY = Integer.MAX_VALUE;
         for (int i = tasks.size() - 1; i >= 0; i--) {
             Task task = tasks.get(i);
 
-            // Skip freeform
-            if (task.isFreeformTask()) {
-                continue;
-            }
-
             // Skip invisible
             float taskProgress = getStackScrollForTask(task);
             if (!currentRange.isInRange(taskProgress)) {
                 continue;
             }
 
-            boolean isFrontMostTaskInGroup = task.group == null || task.group.isFrontMostTask(task);
-            if (isFrontMostTaskInGroup) {
-                getStackTransform(taskProgress, taskProgress, mInitialScrollP, mFocusState,
-                        tmpTransform, null, false /* ignoreSingleTaskCase */,
-                        false /* forceUpdate */);
-                float screenY = tmpTransform.rect.top;
-                boolean hasVisibleThumbnail = (prevScreenY - screenY) > taskBarHeight;
-                if (hasVisibleThumbnail) {
-                    numVisibleThumbnails++;
-                    numVisibleTasks++;
-                    prevScreenY = screenY;
-                } else {
-                    // Once we hit the next front most task that does not have a visible thumbnail,
-                    // walk through remaining visible set
-                    for (int j = i; j >= 0; j--) {
-                        taskProgress = getStackScrollForTask(tasks.get(j));
-                        if (!currentRange.isInRange(taskProgress)) {
-                            break;
-                        }
-                        numVisibleTasks++;
-                    }
-                    break;
-                }
-            } else {
-                // Affiliated task, no thumbnail
+            getStackTransform(taskProgress, taskProgress, mInitialScrollP, mFocusState,
+                    tmpTransform, null, false /* ignoreSingleTaskCase */, false /* forceUpdate */);
+            float screenY = tmpTransform.rect.top;
+            boolean hasVisibleThumbnail = (prevScreenY - screenY) > taskBarHeight;
+            if (hasVisibleThumbnail) {
+                numVisibleThumbnails++;
                 numVisibleTasks++;
+                prevScreenY = screenY;
+            } else {
+                // Once we hit the next front most task that does not have a visible thumbnail,
+                // walk through remaining visible set
+                for (int j = i; j >= 0; j--) {
+                    taskProgress = getStackScrollForTask(tasks.get(j));
+                    if (!currentRange.isInRange(taskProgress)) {
+                        break;
+                    }
+                    numVisibleTasks++;
+                }
+                break;
             }
         }
         return new VisibilityReport(numVisibleTasks, numVisibleThumbnails);
@@ -906,10 +783,7 @@
     public TaskViewTransform getStackTransform(Task task, float stackScroll, int focusState,
             TaskViewTransform transformOut, TaskViewTransform frontTransform, boolean forceUpdate,
             boolean ignoreTaskOverrides) {
-        if (mFreeformLayoutAlgorithm.isTransformAvailable(task, this)) {
-            mFreeformLayoutAlgorithm.getTransform(task, transformOut, this);
-            return transformOut;
-        } else if (useGridLayout()) {
+        if (useGridLayout()) {
             int taskIndex = mTaskIndexMap.get(task.key.id);
             int taskCount = mTaskIndexMap.size();
             mTaskGridLayoutAlgorithm.getTransform(taskIndex, taskCount, transformOut, this);
@@ -1024,7 +898,7 @@
         float z;
         float dimAlpha;
         float viewOutlineAlpha;
-        if (!ssp.hasFreeformWorkspaceSupport() && mNumStackTasks == 1 && !ignoreSingleTaskCase) {
+        if (mNumStackTasks == 1 && !ignoreSingleTaskCase) {
             // When there is exactly one task, then decouple the task from the stack and just move
             // in screen space
             float tmpP = (mMinScrollP - stackScroll) / mNumStackTasks;
@@ -1378,7 +1252,6 @@
         writer.print("insets="); writer.print(Utilities.dumpRect(mSystemInsets));
         writer.print(" stack="); writer.print(Utilities.dumpRect(mStackRect));
         writer.print(" task="); writer.print(Utilities.dumpRect(mTaskRect));
-        writer.print(" freeform="); writer.print(Utilities.dumpRect(mFreeformRect));
         writer.print(" actionButton="); writer.print(Utilities.dumpRect(mStackActionButtonRect));
         writer.println();
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 3160ee0..cda5fb8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -16,22 +16,15 @@
 
 package com.android.systemui.recents.views;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.annotation.IntDef;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Canvas;
 import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.util.ArrayMap;
@@ -64,7 +57,6 @@
 import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
-import com.android.systemui.recents.events.activity.IterateRecentsEvent;
 import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestEvent;
 import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskEvent;
@@ -83,13 +75,11 @@
 import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
 import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
 import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
-import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
 import com.android.systemui.recents.events.ui.UserInteractionEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragStartInitializeDropTargetsEvent;
 import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
@@ -153,8 +143,6 @@
     @ViewDebug.ExportedProperty(deepExport=true, prefix="touch_")
     private TaskStackViewTouchHandler mTouchHandler;
     private TaskStackAnimationHelper mAnimationHelper;
-    private GradientDrawable mFreeformWorkspaceBackground;
-    private ObjectAnimator mFreeformWorkspaceBackgroundAnimator;
     private ViewPool<TaskView, Task> mViewPool;
 
     private ArrayList<TaskView> mTaskViews = new ArrayList<>();
@@ -239,20 +227,6 @@
                 }
             };
 
-    // The drop targets for a task drag
-    private DropTarget mFreeformWorkspaceDropTarget = new DropTarget() {
-        @Override
-        public boolean acceptsDrop(int x, int y, int width, int height, Rect insets,
-                boolean isCurrentTarget) {
-            // This drop target has a fixed bounds and should be checked last, so just fall through
-            // if it is the current target
-            if (!isCurrentTarget) {
-                return mLayoutAlgorithm.mFreeformRect.contains(x, y);
-            }
-            return false;
-        }
-    };
-
     private DropTarget mStackDropTarget = new DropTarget() {
         @Override
         public boolean acceptsDrop(int x, int y, int width, int height, Rect insets,
@@ -312,17 +286,6 @@
             }
         });
         setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-        if (ssp.hasFreeformWorkspaceSupport()) {
-            setWillNotDraw(false);
-        }
-
-        mFreeformWorkspaceBackground = (GradientDrawable) getContext().getDrawable(
-                R.drawable.recents_freeform_workspace_bg);
-        mFreeformWorkspaceBackground.setCallback(this);
-        if (ssp.hasFreeformWorkspaceSupport()) {
-            mFreeformWorkspaceBackground.setColor(
-                    getContext().getColor(R.color.recents_freeform_workspace_bg_color));
-        }
     }
 
     @Override
@@ -359,12 +322,7 @@
         readSystemFlags();
         mTaskViewsClipDirty = true;
         mUIDozeTrigger.stopDozing();
-        if (isResumingFromVisible) {
-            // Animate in the freeform workspace
-            int ffBgAlpha = mLayoutAlgorithm.getStackState().freeformBackgroundAlpha;
-            animateFreeformWorkspaceBackgroundAlpha(ffBgAlpha, new AnimationProps(150,
-                    Interpolators.FAST_OUT_SLOW_IN));
-        } else {
+        if (!isResumingFromVisible) {
             mStackScroller.reset();
             mStableLayoutAlgorithm.reset();
             mLayoutAlgorithm.reset();
@@ -387,7 +345,7 @@
 
         // Only notify if we are already initialized, otherwise, everything will pick up all the
         // new and old tasks when we next layout
-        mStack.setTasks(getContext(), stack, allowNotifyStackChanges && isInitialized);
+        mStack.setTasks(stack, allowNotifyStackChanges && isInitialized);
     }
 
     /** Returns the task stack. */
@@ -422,23 +380,13 @@
 
     /**
      * Returns the front most task view.
-     *
-     * @param stackTasksOnly if set, will return the front most task view in the stack (by default
-     *                       the front most task view will be freeform since they are placed above
-     *                       stack tasks)
      */
-    private TaskView getFrontMostTaskView(boolean stackTasksOnly) {
+    private TaskView getFrontMostTaskView() {
         List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = taskViewCount - 1; i >= 0; i--) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-            if (stackTasksOnly && task.isFreeformTask()) {
-                continue;
-            }
-            return tv;
+        if (taskViews.isEmpty()) {
+            return null;
         }
-        return null;
+        return taskViews.get(taskViews.size() - 1);
     }
 
     /**
@@ -500,8 +448,6 @@
      * visible range includes all tasks at the target stack scroll. This is useful for ensure that
      * all views necessary for a transition or animation will be visible at the start.
      *
-     * This call ignores freeform tasks.
-     *
      * @param taskTransforms The set of task view transforms to reuse, this list will be sized to
      *                       match the size of {@param tasks}
      * @param tasks The set of tasks for which to generate transforms
@@ -554,12 +500,6 @@
                 continue;
             }
 
-            // For freeform tasks, only calculate the stack transform and skip the calculation of
-            // the visible stack indices
-            if (task.isFreeformTask()) {
-                continue;
-            }
-
             frontTransform = transform;
             frontTransformAtTarget = transformAtTarget;
             if (transform.visible) {
@@ -622,7 +562,7 @@
                 transform = mCurrentTaskTransforms.get(taskIndex);
             }
 
-            if (task.isFreeformTask() || (transform != null && transform.visible)) {
+            if (transform != null && transform.visible) {
                 mTmpTaskViewMap.put(task.key, tv);
             } else {
                 if (mTouchExplorationEnabled && Utilities.isDescendentAccessibilityFocused(tv)) {
@@ -643,24 +583,20 @@
                 continue;
             }
 
-            // Skip the invisible non-freeform stack tasks
-            if (!task.isFreeformTask() && !transform.visible) {
+            // Skip the invisible stack tasks
+            if (!transform.visible) {
                 continue;
             }
 
             TaskView tv = mTmpTaskViewMap.get(task.key);
             if (tv == null) {
                 tv = mViewPool.pickUpViewFromPool(task, task);
-                if (task.isFreeformTask()) {
-                    updateTaskViewToTransform(tv, transform, AnimationProps.IMMEDIATE);
+                if (transform.rect.top <= mLayoutAlgorithm.mStackRect.top) {
+                    updateTaskViewToTransform(tv, mLayoutAlgorithm.getBackOfStackTransform(),
+                            AnimationProps.IMMEDIATE);
                 } else {
-                    if (transform.rect.top <= mLayoutAlgorithm.mStackRect.top) {
-                        updateTaskViewToTransform(tv, mLayoutAlgorithm.getBackOfStackTransform(),
-                                AnimationProps.IMMEDIATE);
-                    } else {
-                        updateTaskViewToTransform(tv, mLayoutAlgorithm.getFrontOfStackTransform(),
-                                AnimationProps.IMMEDIATE);
-                    }
+                    updateTaskViewToTransform(tv, mLayoutAlgorithm.getFrontOfStackTransform(),
+                            AnimationProps.IMMEDIATE);
                 }
             } else {
                 // Reattach it in the right z order
@@ -887,13 +823,6 @@
         // Compute the min and max scroll values
         mLayoutAlgorithm.update(mStack, mIgnoreTasks, launchState);
 
-        // Update the freeform workspace background
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.hasFreeformWorkspaceSupport()) {
-            mTmpRect.set(mLayoutAlgorithm.mFreeformRect);
-            mFreeformWorkspaceBackground.setBounds(mTmpRect);
-        }
-
         if (boundScrollToNewMinMax) {
             mStackScroller.boundScroll();
         }
@@ -906,8 +835,7 @@
         mWindowRect.set(mStableWindowRect);
         mStackBounds.set(mStableStackBounds);
         mLayoutAlgorithm.setSystemInsets(mStableLayoutAlgorithm.mSystemInsets);
-        mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds,
-                TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+        mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds);
         updateLayoutAlgorithm(true /* boundScroll */);
     }
 
@@ -1028,21 +956,10 @@
         if (focusedTask != null) {
             if (stackTasksOnly) {
                 List<Task> tasks =  mStack.getStackTasks();
-                if (focusedTask.isFreeformTask()) {
-                    // Try and focus the front most stack task
-                    TaskView tv = getFrontMostTaskView(stackTasksOnly);
-                    if (tv != null) {
-                        newIndex = mStack.indexOfStackTask(tv.getTask());
-                    }
-                } else {
-                    // Try the next task if it is a stack task
-                    int tmpNewIndex = newIndex + (forward ? -1 : 1);
-                    if (0 <= tmpNewIndex && tmpNewIndex < tasks.size()) {
-                        Task t = tasks.get(tmpNewIndex);
-                        if (!t.isFreeformTask()) {
-                            newIndex = tmpNewIndex;
-                        }
-                    }
+                // Try the next task if it is a stack task
+                int tmpNewIndex = newIndex + (forward ? -1 : 1);
+                if (0 <= tmpNewIndex && tmpNewIndex < tasks.size()) {
+                    newIndex = tmpNewIndex;
                 }
             } else {
                 // No restrictions, lets just move to the new task (looping forward/backwards if
@@ -1127,7 +1044,7 @@
                 return tv.getTask();
             }
         }
-        TaskView frontTv = getFrontMostTaskView(true /* stackTasksOnly */);
+        TaskView frontTv = getFrontMostTaskView();
         if (frontTv != null) {
             return frontTv.getTask();
         }
@@ -1278,10 +1195,8 @@
         }
 
         // Compute the rects in the stack algorithm
-        mStableLayoutAlgorithm.initialize(mDisplayRect, mStableWindowRect, mStableStackBounds,
-                TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
-        mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds,
-                TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+        mStableLayoutAlgorithm.initialize(mDisplayRect, mStableWindowRect, mStableStackBounds);
+        mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds);
         updateLayoutAlgorithm(false /* boundScroll */);
 
         // If this is the first layout, then scroll to the front of the stack, then update the
@@ -1404,11 +1319,6 @@
         // Setup the view for the enter animation
         mAnimationHelper.prepareForEnterAnimation();
 
-        // Animate in the freeform workspace
-        int ffBgAlpha = mLayoutAlgorithm.getStackState().freeformBackgroundAlpha;
-        animateFreeformWorkspaceBackgroundAlpha(ffBgAlpha, new AnimationProps(150,
-                Interpolators.FAST_OUT_SLOW_IN));
-
         // Set the task focused state without requesting view focus, and leave the focus animations
         // until after the enter-animation
         RecentsConfiguration config = Recents.getConfiguration();
@@ -1456,43 +1366,6 @@
         return null;
     }
 
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        // Draw the freeform workspace background
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.hasFreeformWorkspaceSupport()) {
-            if (mFreeformWorkspaceBackground.getAlpha() > 0) {
-                mFreeformWorkspaceBackground.draw(canvas);
-            }
-        }
-    }
-
-    @Override
-    protected boolean verifyDrawable(Drawable who) {
-        if (who == mFreeformWorkspaceBackground) {
-            return true;
-        }
-        return super.verifyDrawable(who);
-    }
-
-    /**
-     * Launches the freeform tasks.
-     */
-    public boolean launchFreeformTasks() {
-        ArrayList<Task> tasks = mStack.getFreeformTasks();
-        if (!tasks.isEmpty()) {
-            Task frontTask = tasks.get(tasks.size() - 1);
-            if (frontTask != null && frontTask.isFreeformTask()) {
-                EventBus.getDefault().send(new LaunchTaskEvent(getChildViewForTask(frontTask),
-                        frontTask, null, false));
-                return true;
-            }
-        }
-        return false;
-    }
-
     /**** TaskStackCallbacks Implementation ****/
 
     @Override
@@ -1671,8 +1544,7 @@
         }
 
         // Restore the action button visibility if it is the front most task view
-        if (mScreenPinningEnabled && tv.getTask() ==
-                mStack.getStackFrontMostTask(false /* includeFreeform */)) {
+        if (mScreenPinningEnabled && tv.getTask() == mStack.getStackFrontMostTask()) {
             tv.showActionButton(false /* fadeIn */, 0 /* fadeInDuration */);
         }
     }
@@ -1688,7 +1560,6 @@
 
         // If the doze trigger has already fired, then update the state for this task view
         if (mUIDozeTrigger.isAsleep() ||
-                Recents.getSystemServices().hasFreeformWorkspaceSupport() ||
                 useGridLayout() || Recents.getConfiguration().isLowRamDevice) {
             tv.setNoUserInteractionState();
         }
@@ -1820,21 +1691,17 @@
 
     public final void onBusEvent(LaunchMostRecentTaskRequestEvent event) {
         if (mStack.getTaskCount() > 0) {
-            Task mostRecentTask = mStack.getStackFrontMostTask(true /* includeFreefromTasks */);
+            Task mostRecentTask = mStack.getStackFrontMostTask();
             launchTask(mostRecentTask);
         }
     }
 
     public final void onBusEvent(ShowStackActionButtonEvent event) {
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            mStackActionButtonVisible = true;
-        }
+        mStackActionButtonVisible = true;
     }
 
     public final void onBusEvent(HideStackActionButtonEvent event) {
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            mStackActionButtonVisible = false;
-        }
+        mStackActionButtonVisible = false;
     }
 
     public final void onBusEvent(LaunchNextTaskRequestEvent event) {
@@ -1891,11 +1758,6 @@
         // Start the task animations
         mAnimationHelper.startExitToHomeAnimation(event.animated, event.getAnimationTrigger());
 
-        // Dismiss the freeform workspace background
-        int taskViewExitToHomeDuration = TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION;
-        animateFreeformWorkspaceBackgroundAlpha(0, new AnimationProps(taskViewExitToHomeDuration,
-                Interpolators.FAST_OUT_SLOW_IN));
-
         // Dismiss the grid task view focus frame
         if (mTaskViewFocusFrame != null) {
             mTaskViewFocusFrame.moveGridTaskViewFocus(null);
@@ -1977,8 +1839,7 @@
         mStackScroller.stopScroller();
         mStackScroller.stopBoundScrollAnimation();
 
-        setRelativeFocusedTask(true, false /* stackTasksOnly */, true /* animated */, false,
-                event.timerIndicatorDuration);
+        setRelativeFocusedTask(true, false /* stackTasksOnly */, true /* animated */, false, 0);
     }
 
     public final void onBusEvent(FocusPreviousTaskViewEvent event) {
@@ -2002,8 +1863,7 @@
                     EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
                     break;
                 case DOWN:
-                    EventBus.getDefault().send(
-                        new FocusNextTaskViewEvent(0 /* timerIndicatorDuration */));
+                    EventBus.getDefault().send(new FocusNextTaskViewEvent());
                     break;
             }
         }
@@ -2014,7 +1874,7 @@
         mUIDozeTrigger.poke();
 
         RecentsDebugFlags debugFlags = Recents.getDebugFlags();
-        if (debugFlags.isFastToggleRecentsEnabled() && mFocusedTask != null) {
+        if (mFocusedTask != null) {
             TaskView tv = getChildViewForTask(mFocusedTask);
             if (tv != null) {
                 tv.getHeaderView().cancelFocusTimerIndicator();
@@ -2026,11 +1886,6 @@
         // Ensure that the drag task is not animated
         addIgnoreTask(event.task);
 
-        if (event.task.isFreeformTask()) {
-            // Animate to the front of the stack
-            mStackScroller.animateScroll(mLayoutAlgorithm.mInitialScrollP, null);
-        }
-
         // Enlarge the dragged view slightly
         float finalScale = event.taskView.getScaleX() * DRAG_SCALE_FACTOR;
         mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(),
@@ -2042,14 +1897,6 @@
                 new AnimationProps(DRAG_SCALE_DURATION, Interpolators.FAST_OUT_SLOW_IN));
     }
 
-    public final void onBusEvent(DragStartInitializeDropTargetsEvent event) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.hasFreeformWorkspaceSupport()) {
-            event.handler.registerDropTargetForCurrentDrag(mStackDropTarget);
-            event.handler.registerDropTargetForCurrentDrag(mFreeformWorkspaceDropTarget);
-        }
-    }
-
     public final void onBusEvent(DragDropTargetChangedEvent event) {
         AnimationProps animation = new AnimationProps(SLOW_SYNC_STACK_DURATION,
                 Interpolators.FAST_OUT_SLOW_IN);
@@ -2069,8 +1916,7 @@
                     height, mDividerSize, systemInsets,
                     mLayoutAlgorithm, getResources(), mWindowRect));
             mLayoutAlgorithm.setSystemInsets(systemInsets);
-            mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds,
-                    TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+            mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds);
             updateLayoutAlgorithm(true /* boundScroll */);
             ignoreTaskOverrides = true;
         } else {
@@ -2092,32 +1938,6 @@
             return;
         }
 
-        boolean isFreeformTask = event.task.isFreeformTask();
-        boolean hasChangedWindowingMode =
-                (!isFreeformTask && event.dropTarget == mFreeformWorkspaceDropTarget) ||
-                        (isFreeformTask && event.dropTarget == mStackDropTarget);
-
-        if (hasChangedWindowingMode) {
-            // Move the task to the right position in the stack (ie. the front of the stack if
-            // freeform or the front of the stack if fullscreen). Note, we MUST move the tasks
-            // before we update their stack ids, otherwise, the keys will have changed.
-            if (event.dropTarget == mFreeformWorkspaceDropTarget) {
-                mStack.setTaskWindowingMode(event.task, WINDOWING_MODE_FREEFORM);
-            } else if (event.dropTarget == mStackDropTarget) {
-                mStack.setTaskWindowingMode(event.task, WINDOWING_MODE_FULLSCREEN);
-            }
-            updateLayoutAlgorithm(true /* boundScroll */);
-
-            // Move the task to the new stack in the system after the animation completes
-            event.addPostAnimationCallback(new Runnable() {
-                @Override
-                public void run() {
-                    SystemServicesProxy ssp = Recents.getSystemServices();
-                    ssp.setTaskWindowingMode(event.task.key.id, event.task.key.windowingMode);
-                }
-            });
-        }
-
         // Restore the task, so that relayout will apply to it below
         removeIgnoreTask(event.task);
 
@@ -2152,13 +1972,6 @@
         event.getAnimationTrigger().increment();
     }
 
-    public final void onBusEvent(IterateRecentsEvent event) {
-        if (!mEnterAnimationComplete) {
-            // Cancel the previous task's window transition before animating the focused state
-            EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null));
-        }
-    }
-
     public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
         mEnterAnimationComplete = true;
         tryStartEnterAnimation();
@@ -2177,9 +1990,7 @@
             // Add a runnable to the post animation ref counter to clear all the views
             trigger.addLastDecrementRunnable(() -> {
                 // Start the dozer to trigger to trigger any UI that shows after a timeout
-                if (!Recents.getSystemServices().hasFreeformWorkspaceSupport()) {
-                    mUIDozeTrigger.startDozing();
-                }
+                mUIDozeTrigger.startDozing();
 
                 // Update the focused state here -- since we only set the focused task without
                 // requesting view focus in onFirstLayout(), actually request view focus and
@@ -2202,18 +2013,6 @@
         mStackReloaded = false;
     }
 
-    public final void onBusEvent(UpdateFreeformTaskViewVisibilityEvent event) {
-        List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-            if (task.isFreeformTask()) {
-                tv.setVisibility(event.visible ? View.VISIBLE : View.INVISIBLE);
-            }
-        }
-    }
-
     public final void onBusEvent(final MultiWindowStateChangedEvent event) {
         if (event.inMultiWindow || !event.showDeferredAnimation) {
             setTasks(event.stack, true /* allowNotifyStackChanges */);
@@ -2315,27 +2114,6 @@
     }
 
     /**
-     * Starts an alpha animation on the freeform workspace background.
-     */
-    private void animateFreeformWorkspaceBackgroundAlpha(int targetAlpha,
-            AnimationProps animation) {
-        if (mFreeformWorkspaceBackground.getAlpha() == targetAlpha) {
-            return;
-        }
-
-        Utilities.cancelAnimationWithoutCallbacks(mFreeformWorkspaceBackgroundAnimator);
-        mFreeformWorkspaceBackgroundAnimator = ObjectAnimator.ofInt(mFreeformWorkspaceBackground,
-                Utilities.DRAWABLE_ALPHA, mFreeformWorkspaceBackground.getAlpha(), targetAlpha);
-        mFreeformWorkspaceBackgroundAnimator.setStartDelay(
-                animation.getDuration(AnimationProps.ALPHA));
-        mFreeformWorkspaceBackgroundAnimator.setDuration(
-                animation.getDuration(AnimationProps.ALPHA));
-        mFreeformWorkspaceBackgroundAnimator.setInterpolator(
-                animation.getInterpolator(AnimationProps.ALPHA));
-        mFreeformWorkspaceBackgroundAnimator.start();
-    }
-
-    /**
      * Returns the insert index for the task in the current set of task views. If the given task
      * is already in the task view list, then this method returns the insert index assuming it
      * is first removed at the previous index.
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 32a249c..1abaced 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -403,18 +403,6 @@
             return;
         }
 
-        // If tapping on the freeform workspace background, just launch the first freeform task
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.hasFreeformWorkspaceSupport()) {
-            Rect freeformRect = mSv.mLayoutAlgorithm.mFreeformRect;
-            if (freeformRect.top <= y && y <= freeformRect.bottom) {
-                if (mSv.launchFreeformTasks()) {
-                    // TODO: Animate Recents away as we launch the freeform tasks
-                    return;
-                }
-            }
-        }
-
         // The user intentionally tapped on the background, which is like a tap on the "desktop".
         // Hide recents and transition to the launcher.
         EventBus.getDefault().send(new HideRecentsEvent(false, true));
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 9d63964..a75034a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.recents.views;
 
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-
 import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
@@ -196,9 +194,7 @@
      * Called from RecentsActivity when it is relaunched.
      */
     void onReload(boolean isResumingFromVisible) {
-        if (!Recents.getSystemServices().hasFreeformWorkspaceSupport()) {
-            resetNoUserInteractionState();
-        }
+        resetNoUserInteractionState();
         if (!isResumingFromVisible) {
             resetViewProperties();
         }
@@ -415,9 +411,7 @@
      * view.
      */
     boolean shouldClipViewInStack() {
-        // Never clip for freeform tasks or if invisible
-        if (mTask.isFreeformTask() || getVisibility() != View.VISIBLE ||
-                Recents.getConfiguration().isLowRamDevice) {
+        if (getVisibility() != View.VISIBLE || Recents.getConfiguration().isLowRamDevice) {
             return false;
         }
         return mClipViewInStack;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 198ecae..1420a01 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -17,7 +17,6 @@
 package com.android.systemui.recents.views;
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
@@ -164,8 +163,6 @@
     float mDimAlpha;
     Drawable mLightDismissDrawable;
     Drawable mDarkDismissDrawable;
-    Drawable mLightFreeformIcon;
-    Drawable mDarkFreeformIcon;
     Drawable mLightFullscreenIcon;
     Drawable mDarkFullscreenIcon;
     Drawable mLightInfoIcon;
@@ -215,8 +212,6 @@
         mHighlightHeight = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight);
         mTaskBarViewLightTextColor = context.getColor(R.color.recents_task_bar_light_text_color);
         mTaskBarViewDarkTextColor = context.getColor(R.color.recents_task_bar_dark_text_color);
-        mLightFreeformIcon = context.getDrawable(R.drawable.recents_move_task_freeform_light);
-        mDarkFreeformIcon = context.getDrawable(R.drawable.recents_move_task_freeform_dark);
         mLightFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_light);
         mDarkFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_dark);
         mLightInfoIcon = context.getDrawable(R.drawable.recents_info_light);
@@ -249,9 +244,6 @@
         mIconView.setOnLongClickListener(this);
         mTitleView = findViewById(R.id.title);
         mDismissButton = findViewById(R.id.dismiss_task);
-        if (ssp.hasFreeformWorkspaceSupport()) {
-            mMoveTaskButton = findViewById(R.id.move_task);
-        }
 
         onConfigurationChanged();
     }
@@ -341,20 +333,6 @@
         boolean showDismissIcon = true;
         int rightInset = width - getMeasuredWidth();
 
-        if (mTask != null && mTask.isFreeformTask()) {
-            // For freeform tasks, we always show the app icon, and only show the title, move-task
-            // icon, and the dismiss icon if there is room
-            int appIconWidth = mIconView.getMeasuredWidth();
-            int titleWidth = (int) mTitleView.getPaint().measureText(mTask.title);
-            int dismissWidth = mDismissButton.getMeasuredWidth();
-            int moveTaskWidth = mMoveTaskButton != null
-                    ? mMoveTaskButton.getMeasuredWidth()
-                    : 0;
-            showTitle = width >= (appIconWidth + dismissWidth + moveTaskWidth + titleWidth);
-            showMoveIcon = width >= (appIconWidth + dismissWidth + moveTaskWidth);
-            showDismissIcon = width >= (appIconWidth + dismissWidth);
-        }
-
         mTitleView.setVisibility(showTitle ? View.VISIBLE : View.INVISIBLE);
         if (mMoveTaskButton != null) {
             mMoveTaskButton.setVisibility(showMoveIcon ? View.VISIBLE : View.INVISIBLE);
@@ -482,36 +460,6 @@
         mDismissButton.setClickable(false);
         ((RippleDrawable) mDismissButton.getBackground()).setForceSoftware(true);
 
-        // When freeform workspaces are enabled, then update the move-task button depending on the
-        // current task
-        if (mMoveTaskButton != null) {
-            if (t.isFreeformTask()) {
-                mTaskWindowingMode = WINDOWING_MODE_FULLSCREEN;
-                mMoveTaskButton.setImageDrawable(t.useLightOnPrimaryColor
-                        ? mLightFullscreenIcon
-                        : mDarkFullscreenIcon);
-            } else {
-                mTaskWindowingMode = WINDOWING_MODE_FREEFORM;
-                mMoveTaskButton.setImageDrawable(t.useLightOnPrimaryColor
-                        ? mLightFreeformIcon
-                        : mDarkFreeformIcon);
-            }
-            mMoveTaskButton.setOnClickListener(this);
-            mMoveTaskButton.setClickable(false);
-            ((RippleDrawable) mMoveTaskButton.getBackground()).setForceSoftware(true);
-        }
-
-        if (Recents.getDebugFlags().isFastToggleRecentsEnabled()) {
-            if (mFocusTimerIndicator == null) {
-                mFocusTimerIndicator = (ProgressBar) Utilities.findViewStubById(this,
-                        R.id.focus_timer_indicator_stub).inflate();
-            }
-            mFocusTimerIndicator.getProgressDrawable()
-                    .setColorFilter(
-                            getSecondaryColor(t.colorPrimary, t.useLightOnPrimaryColor),
-                            PorterDuff.Mode.SRC_IN);
-        }
-
         // In accessibility, a single click on the focused app info button will show it
         if (touchExplorationEnabled) {
             mIconView.setContentDescription(t.appInfoDescription);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index a2190b3..d0ebc8d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -245,10 +245,6 @@
     public void updateThumbnailMatrix() {
         mThumbnailScale = 1f;
         if (mBitmapShader != null && mThumbnailData != null) {
-            // We consider this a stack task if it is not freeform (ie. has no bounds) or has been
-            // dragged into the stack from the freeform workspace
-            boolean isStackTask = !mTask.isFreeformTask() || mTask.bounds == null;
-            int xOffset, yOffset = 0;
             if (mTaskViewRect.isEmpty()) {
                 // If we haven't measured , skip the thumbnail drawing and only draw the background
                 // color
@@ -266,7 +262,7 @@
                     mThumbnailScale = (float) (mTaskViewRect.height() - mTitleBarHeight)
                             / (float) mThumbnailRect.height();
                 }
-            } else if (isStackTask) {
+            } else {
                 float invThumbnailScale = 1f / mFullscreenThumbnailScale;
                 if (mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT) {
                     if (mThumbnailData.orientation == Configuration.ORIENTATION_PORTRAIT) {
@@ -283,12 +279,6 @@
                     // Otherwise, scale the screenshot to fit 1:1 in the current orientation
                     mThumbnailScale = invThumbnailScale;
                 }
-            } else {
-                // Otherwise, if this is a freeform task with task bounds, then scale the thumbnail
-                // to fit the entire bitmap into the task bounds
-                mThumbnailScale = Math.min(
-                        (float) mTaskViewRect.width() / mThumbnailRect.width(),
-                        (float) mTaskViewRect.height() / mThumbnailRect.height());
             }
             mMatrix.setTranslate(-mThumbnailData.insets.left * mFullscreenThumbnailScale,
                     -mThumbnailData.insets.top * mFullscreenThumbnailScale);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
index 397f24e..c9dbe2a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -59,7 +59,7 @@
 
     public boolean visible = false;
 
-    // This is a window-space rect used for positioning the task in the stack and freeform workspace
+    // This is a window-space rect used for positioning the task in the stack
     public RectF rect = new RectF();
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 7699bb9..9211e3f 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.shortcut;
 
+import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
+import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
+import static android.os.UserHandle.USER_CURRENT;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.ActivityManager;
 import android.app.IActivityManager;
@@ -102,11 +106,10 @@
                 // If there is no window docked, we dock the top-most window.
                 Recents recents = getComponent(Recents.class);
                 int dockMode = (shortcutCode == SC_DOCK_LEFT)
-                        ? ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
-                        : ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
+                        ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
+                        : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
                 List<ActivityManager.RecentTaskInfo> taskList =
-                        SystemServicesProxy.getInstance(mContext).getRecentTasks(1,
-                                UserHandle.USER_CURRENT, false, new ArraySet<>());
+                        SystemServicesProxy.getInstance(mContext).getRecentTasks(1, USER_CURRENT);
                 recents.showRecentApps(
                         false /* triggeredFromAltTab */,
                         false /* fromHome */);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index 578a18a..0997983 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -32,7 +32,7 @@
 import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
 import com.android.systemui.recents.events.component.ShowUserToastEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.recents.misc.TaskStackChangeListener;
 import com.android.systemui.stackdivider.events.StartedDragingEvent;
 import com.android.systemui.stackdivider.events.StoppedDragingEvent;
 
@@ -76,7 +76,7 @@
         mContext = context;
         EventBus.getDefault().register(this);
         SystemServicesProxy.getInstance(context).registerTaskStackListener(
-                new TaskStackListener() {
+                new TaskStackChangeListener() {
                     @Override
                     public void onActivityForcedResizable(String packageName, int taskId,
                             int reason) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 966e789..6c5f4b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -36,6 +36,7 @@
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Property;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.NotificationHeaderView;
@@ -174,6 +175,11 @@
     private boolean mShowNoBackground;
     private ExpandableNotificationRow mNotificationParent;
     private OnExpandClickListener mOnExpandClickListener;
+
+    // Listener will be called when receiving a long click event.
+    // Use #setLongPressPosition to optionally assign positional data with the long press.
+    private LongPressListener mLongPressListener;
+
     private boolean mGroupExpansionChanging;
 
     /**
@@ -788,6 +794,10 @@
         mOnExpandClickListener = onExpandClickListener;
     }
 
+    public void setLongPressListener(LongPressListener longPressListener) {
+        mLongPressListener = longPressListener;
+    }
+
     @Override
     public void setOnClickListener(@Nullable OnClickListener l) {
         super.setOnClickListener(l);
@@ -1338,6 +1348,47 @@
         }
     }
 
+    private void doLongClickCallback() {
+        doLongClickCallback(getWidth() / 2, getHeight() / 2);
+    }
+
+    public void doLongClickCallback(int x, int y) {
+        createMenu();
+        MenuItem menuItem = getProvider().getLongpressMenuItem(mContext);
+        if (mLongPressListener != null && menuItem != null) {
+            mLongPressListener.onLongPress(this, x, y, menuItem);
+        }
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (KeyEvent.isConfirmKey(keyCode)) {
+            event.startTracking();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        if (KeyEvent.isConfirmKey(keyCode)) {
+            if (!event.isCanceled()) {
+                performClick();
+            }
+            return true;
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+        if (KeyEvent.isConfirmKey(keyCode)) {
+            doLongClickCallback();
+            return true;
+        }
+        return false;
+    }
+
     public void resetTranslation() {
         if (mTranslateAnim != null) {
             mTranslateAnim.cancel();
@@ -2205,6 +2256,7 @@
     @Override
     public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfoInternal(info);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
         if (canViewBeDismissed()) {
             info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
         }
@@ -2244,6 +2296,9 @@
             case AccessibilityNodeInfo.ACTION_EXPAND:
                 mExpandClickListener.onClick(this);
                 return true;
+            case AccessibilityNodeInfo.ACTION_LONG_CLICK:
+                doLongClickCallback();
+                return true;
         }
         return false;
     }
@@ -2332,4 +2387,15 @@
     protected void setChildrenContainer(NotificationChildrenContainer childrenContainer) {
         mChildrenContainer = childrenContainer;
     }
+
+    /**
+     * Equivalent to View.OnLongClickListener with coordinates
+     */
+    public interface LongPressListener {
+        /**
+         * Equivalent to {@link View.OnLongClickListener#onLongClick(View)} with coordinates
+         * @return whether the longpress was handled
+         */
+        boolean onLongPress(View v, int x, int y, MenuItem item);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 59d3e0a..fed2ebe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -36,14 +36,18 @@
 import android.view.WindowManager;
 import android.widget.LinearLayout;
 
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
+import com.android.systemui.Prefs;
 import com.android.systemui.R;
-import com.android.systemui.SwipeHelper;
+import com.android.systemui.classifier.FalsingLog;
+import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.recents.misc.TaskStackChangeListener;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
@@ -51,10 +55,6 @@
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.classifier.FalsingLog;
-import com.android.systemui.classifier.FalsingManager;
-import com.android.systemui.Prefs;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -247,11 +247,12 @@
     }
 
     /**
-     * Returns the {@link com.android.systemui.SwipeHelper.LongPressListener} that will be
-     * triggered when a notification card is long-pressed.
+     * Returns the
+     * {@link com.android.systemui.statusbar.ExpandableNotificationRow.LongPressListener} that will
+     * be triggered when a notification card is long-pressed.
      */
     @Override
-    protected SwipeHelper.LongPressListener getNotificationLongClicker() {
+    protected ExpandableNotificationRow.LongPressListener getNotificationLongClicker() {
         // For the automative use case, we do not want to the user to be able to interact with
         // a notification other than a regular click. As a result, just return null for the
         // long click listener.
@@ -304,10 +305,10 @@
     }
 
     /**
-     * An implementation of TaskStackListener, that listens for changes in the system task
+     * An implementation of TaskStackChangeListener, that listens for changes in the system task
      * stack and notifies the navigation bar.
      */
-    private class TaskStackListenerImpl extends TaskStackListener {
+    private class TaskStackListenerImpl extends TaskStackChangeListener {
         @Override
         public void onTaskStackChanged() {
             SystemServicesProxy ssp = Recents.getSystemServices();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 7b11ace..af03440 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -704,7 +704,7 @@
                     mInitialHeightOnTouch = mQsExpansionHeight;
                     mQsTracking = true;
                     mIntercepting = false;
-                    mNotificationStackScroller.removeLongPressCallback();
+                    mNotificationStackScroller.cancelLongPress();
                 }
                 break;
             case MotionEvent.ACTION_POINTER_UP:
@@ -740,7 +740,7 @@
                     mInitialTouchY = y;
                     mInitialTouchX = x;
                     mIntercepting = false;
-                    mNotificationStackScroller.removeLongPressCallback();
+                    mNotificationStackScroller.cancelLongPress();
                     return true;
                 }
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 9c837ed..b876286 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -66,7 +66,7 @@
 import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.recents.misc.TaskStackChangeListener;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
 import com.android.systemui.statusbar.policy.BluetoothController;
@@ -639,12 +639,17 @@
     }
 
     private Intent getTaskIntent(int taskId, int userId) {
-        List<ActivityManager.RecentTaskInfo> tasks = mContext.getSystemService(ActivityManager.class)
-                .getRecentTasksForUser(NUM_TASKS_FOR_INSTANT_APP_INFO, 0, userId);
-        for (int i = 0; i < tasks.size(); i++) {
-            if (tasks.get(i).id == taskId) {
-                return tasks.get(i).baseIntent;
+        try {
+            final List<ActivityManager.RecentTaskInfo> tasks =
+                    ActivityManager.getService().getRecentTasks(
+                            NUM_TASKS_FOR_INSTANT_APP_INFO, 0, userId).getList();
+            for (int i = 0; i < tasks.size(); i++) {
+                if (tasks.get(i).id == taskId) {
+                    return tasks.get(i).baseIntent;
+                }
             }
+        } catch (RemoteException e) {
+            // Fall through
         }
         return null;
     }
@@ -763,7 +768,7 @@
         mIconController.setIconVisibility(mSlotDataSaver, isDataSaving);
     }
 
-    private final TaskStackListener mTaskListener = new TaskStackListener() {
+    private final TaskStackChangeListener mTaskListener = new TaskStackChangeListener() {
         @Override
         public void onTaskStackChanged() {
             // Listen for changes to stacks and then check which instant apps are foreground.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 54be857..9f03954 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -160,7 +160,6 @@
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
-import com.android.systemui.SwipeHelper;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
@@ -4838,7 +4837,7 @@
 
     @Override
     public void onTouchSlopExceeded() {
-        mStackScroller.removeLongPressCallback();
+        mStackScroller.cancelLongPress();
         mStackScroller.checkSnoozeLeavebehind();
     }
 
@@ -5470,7 +5469,7 @@
 
         @Override
         public void onDoubleTap(float screenX, float screenY) {
-            if (screenX > 0 && screenY > 0 && mAmbientIndicationContainer != null 
+            if (screenX > 0 && screenY > 0 && mAmbientIndicationContainer != null
                 && mAmbientIndicationContainer.getVisibility() == View.VISIBLE) {
                 mAmbientIndicationContainer.getLocationOnScreen(mTmpInt2);
                 float viewX = screenX - mTmpInt2[0];
@@ -5882,8 +5881,7 @@
                 List<ActivityManager.RecentTaskInfo> recentTask = null;
                 try {
                     recentTask = ActivityManager.getService().getRecentTasks(1,
-                            ActivityManager.RECENT_WITH_EXCLUDED
-                            | ActivityManager.RECENT_INCLUDE_PROFILES,
+                            ActivityManager.RECENT_WITH_EXCLUDED,
                             mCurrentUserId).getList();
                 } catch (RemoteException e) {
                     // Abandon hope activity manager not running.
@@ -6296,14 +6294,15 @@
                 true /* removeControls */, x, y, true /* resetMenu */);
     }
 
-    protected SwipeHelper.LongPressListener getNotificationLongClicker() {
-        return new SwipeHelper.LongPressListener() {
+    protected ExpandableNotificationRow.LongPressListener getNotificationLongClicker() {
+        return new ExpandableNotificationRow.LongPressListener() {
             @Override
             public boolean onLongPress(View v, final int x, final int y,
                     MenuItem item) {
                 if (!(v instanceof ExpandableNotificationRow)) {
                     return false;
                 }
+
                 if (v.getWindowToken() == null) {
                     Log.e(TAG, "Trying to show notification guts, but not attached to window");
                     return false;
@@ -6318,7 +6317,7 @@
                     closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
                             true /* removeControls */, -1 /* x */, -1 /* y */,
                             true /* resetMenu */);
-                    return false;
+                    return true;
                 }
                 bindGuts(row, item);
                 NotificationGuts guts = row.getGuts();
@@ -6598,6 +6597,7 @@
         row.setRemoteViewClickHandler(mOnClickHandler);
         row.setInflationCallback(this);
         row.setSecureStateProvider(this::isKeyguardCurrentlySecure);
+        row.setLongPressListener(getNotificationLongClicker());
 
         // Get the app name.
         // Note that Notification.Builder#bindHeaderAppName has similar logic
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 75532d9..1e14626 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -240,7 +240,7 @@
      * motion.
      */
     private int mMaxScrollAfterExpand;
-    private SwipeHelper.LongPressListener mLongPressListener;
+    private ExpandableNotificationRow.LongPressListener mLongPressListener;
 
     private NotificationMenuRowPlugin mCurrMenuRow;
     private View mTranslatingParentView;
@@ -410,7 +410,6 @@
         mExpandHelper.setEventSource(this);
         mExpandHelper.setScrollAdapter(this);
         mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, this, getContext());
-        mSwipeHelper.setLongPressListener(mLongPressListener);
         mStackScrollAlgorithm = createStackScrollAlgorithm(context);
         initView(context);
         mFalsingManager = FalsingManager.getInstance(context);
@@ -884,8 +883,7 @@
         return firstChild != null ? firstChild.getMinHeight() : mCollapsedSize;
     }
 
-    public void setLongPressListener(SwipeHelper.LongPressListener listener) {
-        mSwipeHelper.setLongPressListener(listener);
+    public void setLongPressListener(ExpandableNotificationRow.LongPressListener listener) {
         mLongPressListener = listener;
     }
 
@@ -1175,7 +1173,7 @@
         if (v instanceof ExpandableNotificationRow) {
             ((ExpandableNotificationRow) v).setUserLocked(userLocked);
         }
-        removeLongPressCallback();
+        cancelLongPress();
         requestDisallowInterceptTouchEvent(true);
     }
 
@@ -2581,7 +2579,7 @@
     public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
         super.requestDisallowInterceptTouchEvent(disallowIntercept);
         if (disallowIntercept) {
-            mSwipeHelper.removeLongPressCallback();
+            cancelLongPress();
         }
     }
 
@@ -3302,7 +3300,7 @@
         mIsBeingDragged = isDragged;
         if (isDragged) {
             requestDisallowInterceptTouchEvent(true);
-            removeLongPressCallback();
+            cancelLongPress();
         }
     }
 
@@ -3310,7 +3308,7 @@
     public void onWindowFocusChanged(boolean hasWindowFocus) {
         super.onWindowFocusChanged(hasWindowFocus);
         if (!hasWindowFocus) {
-            removeLongPressCallback();
+            cancelLongPress();
         }
     }
 
@@ -3324,7 +3322,7 @@
 
     @Override
     public void requestDisallowLongPress() {
-        removeLongPressCallback();
+        cancelLongPress();
     }
 
     @Override
@@ -3332,8 +3330,8 @@
         mDisallowDismissInThisMotion = true;
     }
 
-    public void removeLongPressCallback() {
-        mSwipeHelper.removeLongPressCallback();
+    public void cancelLongPress() {
+        mSwipeHelper.cancelLongPress();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
index b835909..5ec3dff 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
@@ -23,7 +23,7 @@
  */
 public class DelayedWakeLock implements WakeLock {
 
-    private static final long RELEASE_DELAY_MS = 100;
+    private static final long RELEASE_DELAY_MS = 120;
 
     private final Handler mHandler;
     private final WakeLock mInner;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
index 5fb0a3e..b86fc21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
@@ -44,7 +44,7 @@
 import com.android.systemui.keyguard.WorkLockActivity;
 import com.android.systemui.keyguard.WorkLockActivityController;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.recents.misc.TaskStackChangeListener;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -68,7 +68,7 @@
     private @Mock IActivityManager mIActivityManager;
 
     private WorkLockActivityController mController;
-    private TaskStackListener mTaskStackListener;
+    private TaskStackChangeListener mTaskStackListener;
 
     @Before
     public void setUp() throws Exception {
@@ -78,8 +78,8 @@
         doReturn("com.example.test").when(mContext).getPackageName();
 
         // Construct controller. Save the TaskStackListener for injecting events.
-        final ArgumentCaptor<TaskStackListener> listenerCaptor =
-                ArgumentCaptor.forClass(TaskStackListener.class);
+        final ArgumentCaptor<TaskStackChangeListener> listenerCaptor =
+                ArgumentCaptor.forClass(TaskStackChangeListener.class);
         mController =
                 new WorkLockActivityController(mContext, mSystemServicesProxy, mIActivityManager);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java
index 767e124..4564c8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java
@@ -60,7 +60,7 @@
         MockitoAnnotations.initMocks(this);
         mLoader = new HighResThumbnailLoader(mMockSystemServicesProxy, Looper.getMainLooper(),
                 false);
-        mTask.key = new TaskKey(0, WINDOWING_MODE_UNDEFINED, null, 0, 0, 0);
+        mTask.key = new TaskKey(0, WINDOWING_MODE_UNDEFINED, null, 0, 0);
         when(mMockSystemServicesProxy.getTaskThumbnail(anyInt(), anyBoolean()))
                 .thenReturn(mThumbnailData);
         mLoader.setVisible(true);
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index e17a6a6..8e88359 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4665,6 +4665,40 @@
     // OS: P
     DIALOG_CLEAR_ADB_KEYS = 1223;
 
+    // Open: Settings > Developer options > Quick setting tile config
+    // CATEGORY: SETTINGS
+    // OS: P
+    DEVELOPMENT_QS_TILE_CONFIG = 1224;
+
+    // OPEN: Settings > Developer options > Store logger data persistently on device > Info dialog
+    // CATEGORY: SETTINGS
+    // OS: P
+    DIALOG_LOG_PERSIST = 1225;
+
+    // ACTION: DND Settings > Priority only allows > Alarms toggle
+    // SUBTYPE: 0 is off, 1 is on
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_ZEN_ALLOW_ALARMS = 1226;
+
+    // ACTION: DND Settings > Priority only allows > Media toggle
+    // SUBTYPE: 0 is off, 1 is on
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_ZEN_ALLOW_MEDIA = 1227;
+
+    // An autofill service explicitly defined which view should commit the autofill context
+    // Package: Package of app that is autofilled
+    // OS: P
+    // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    AUTOFILL_EXPLICIT_SAVE_TRIGGER_DEFINITION = 1228;
+
+    // The autofill context was commited when the user clicked a view explicitly marked by the
+    // service as committing it
+    // Package: Package of app that is autofilled
+    // OS: P
+    AUTOFILL_SAVE_EXPLICITLY_TRIGGERED = 1229;
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index f9f6bf7..b32be73 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1328,7 +1328,7 @@
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
                                                   (RsType)type, (RsAllocationMipmapControl)mip,
-                                                  ptr, bitmap.getSize(), usage);
+                                                  ptr, bitmap.computeByteSize(), usage);
     return id;
 }
 
@@ -1356,7 +1356,7 @@
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
                                                       (RsType)type, (RsAllocationMipmapControl)mip,
-                                                      ptr, bitmap.getSize(), usage);
+                                                      ptr, bitmap.computeByteSize(), usage);
     return id;
 }
 
@@ -1371,7 +1371,7 @@
     const void* ptr = bitmap.getPixels();
     rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0,
                        0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
-                       w, h, ptr, bitmap.getSize(), 0);
+                       w, h, ptr, bitmap.computeByteSize(), 0);
 }
 
 static void
@@ -1381,7 +1381,7 @@
     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
 
     void* ptr = bitmap.getPixels();
-    rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.getSize());
+    rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.computeByteSize());
     bitmap.notifyPixelsChanged();
 }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index c60647f..47d21f8 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -366,6 +366,11 @@
     }
 
     @Override
+    public EventStreamTransformation getNext() {
+        return null;
+    }
+
+    @Override
     public void clearEvents(int inputSource) {
         /* do nothing */
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/AutoclickController.java b/services/accessibility/java/com/android/server/accessibility/AutoclickController.java
index 892e9da..f5b0eb1 100644
--- a/services/accessibility/java/com/android/server/accessibility/AutoclickController.java
+++ b/services/accessibility/java/com/android/server/accessibility/AutoclickController.java
@@ -23,15 +23,12 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.provider.Settings;
-import android.util.Slog;
 import android.view.InputDevice;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.MotionEvent.PointerCoords;
 import android.view.MotionEvent.PointerProperties;
-import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 
 /**
@@ -55,11 +52,10 @@
  *
  * Each instance is associated to a single user (and it does not handle user switch itself).
  */
-public class AutoclickController implements EventStreamTransformation {
+public class AutoclickController extends BaseEventStreamTransformation {
 
     private static final String LOG_TAG = AutoclickController.class.getSimpleName();
 
-    private EventStreamTransformation mNext;
     private final Context mContext;
     private final int mUserId;
 
@@ -88,9 +84,7 @@
             mClickScheduler.cancel();
         }
 
-        if (mNext != null) {
-            mNext.onMotionEvent(event, rawEvent, policyFlags);
-        }
+        super.onMotionEvent(event, rawEvent, policyFlags);
     }
 
     @Override
@@ -103,21 +97,7 @@
             }
         }
 
-        if (mNext != null) {
-          mNext.onKeyEvent(event, policyFlags);
-        }
-    }
-
-    @Override
-    public void onAccessibilityEvent(AccessibilityEvent event) {
-        if (mNext != null) {
-            mNext.onAccessibilityEvent(event);
-        }
-    }
-
-    @Override
-    public void setNext(EventStreamTransformation next) {
-        mNext = next;
+        super.onKeyEvent(event, policyFlags);
     }
 
     @Override
@@ -126,9 +106,7 @@
             mClickScheduler.cancel();
         }
 
-        if (mNext != null) {
-            mNext.clearEvents(inputSource);
-        }
+        super.clearEvents(inputSource);
     }
 
     @Override
@@ -418,7 +396,7 @@
          * Creates and forwards click event sequence.
          */
         private void sendClick() {
-            if (mLastMotionEvent == null || mNext == null) {
+            if (mLastMotionEvent == null || getNext() == null) {
                 return;
             }
 
@@ -448,10 +426,10 @@
             MotionEvent upEvent = MotionEvent.obtain(downEvent);
             upEvent.setAction(MotionEvent.ACTION_UP);
 
-            mNext.onMotionEvent(downEvent, downEvent, mEventPolicyFlags);
+            AutoclickController.super.onMotionEvent(downEvent, downEvent, mEventPolicyFlags);
             downEvent.recycle();
 
-            mNext.onMotionEvent(upEvent, upEvent, mEventPolicyFlags);
+            AutoclickController.super.onMotionEvent(upEvent, upEvent, mEventPolicyFlags);
             upEvent.recycle();
         }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/BaseEventStreamTransformation.java b/services/accessibility/java/com/android/server/accessibility/BaseEventStreamTransformation.java
new file mode 100644
index 0000000..ce54586
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/BaseEventStreamTransformation.java
@@ -0,0 +1,31 @@
+/*
+ ** Copyright 2017, 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.server.accessibility;
+
+abstract class BaseEventStreamTransformation implements EventStreamTransformation {
+    private EventStreamTransformation mNext;
+
+    @Override
+    public void setNext(EventStreamTransformation next) {
+        mNext = next;
+    }
+
+    @Override
+    public EventStreamTransformation getNext() {
+        return mNext;
+    }
+}
\ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/EventStreamTransformation.java b/services/accessibility/java/com/android/server/accessibility/EventStreamTransformation.java
index fdc4098..7982996 100644
--- a/services/accessibility/java/com/android/server/accessibility/EventStreamTransformation.java
+++ b/services/accessibility/java/com/android/server/accessibility/EventStreamTransformation.java
@@ -65,7 +65,12 @@
      * @param rawEvent The raw motion event.
      * @param policyFlags Policy flags for the event.
      */
-    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags);
+    default void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+        EventStreamTransformation next = getNext();
+        if (next != null) {
+            next.onMotionEvent(event, rawEvent, policyFlags);
+        }
+    }
 
     /**
      * Receives a key event.
@@ -73,14 +78,24 @@
      * @param event The key event.
      * @param policyFlags Policy flags for the event.
      */
-    public void onKeyEvent(KeyEvent event, int policyFlags);
+    default void onKeyEvent(KeyEvent event, int policyFlags) {
+        EventStreamTransformation next = getNext();
+        if (next != null) {
+            next.onKeyEvent(event, policyFlags);
+        }
+    }
 
     /**
      * Receives an accessibility event.
      *
      * @param event The accessibility event.
      */
-    public void onAccessibilityEvent(AccessibilityEvent event);
+    default void onAccessibilityEvent(AccessibilityEvent event) {
+        EventStreamTransformation next = getNext();
+        if (next != null) {
+            next.onAccessibilityEvent(event);
+        }
+    };
 
     /**
      * Sets the next transformation.
@@ -90,14 +105,26 @@
     public void setNext(EventStreamTransformation next);
 
     /**
+     * Gets the next transformation.
+     *
+     * @return The next transformation.
+     */
+    public EventStreamTransformation getNext();
+
+    /**
      * Clears internal state associated with events from specific input source.
      *
      * @param inputSource The input source class for which transformation state should be cleared.
      */
-    public void clearEvents(int inputSource);
+    default void clearEvents(int inputSource) {
+        EventStreamTransformation next = getNext();
+        if (next != null) {
+            next.clearEvents(inputSource);
+        }
+    }
 
     /**
      * Destroys this transformation.
      */
-    public void onDestroy();
+    default void onDestroy() {}
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/KeyboardInterceptor.java b/services/accessibility/java/com/android/server/accessibility/KeyboardInterceptor.java
index f00a954..7724945 100644
--- a/services/accessibility/java/com/android/server/accessibility/KeyboardInterceptor.java
+++ b/services/accessibility/java/com/android/server/accessibility/KeyboardInterceptor.java
@@ -22,14 +22,12 @@
 import android.util.Pools;
 import android.util.Slog;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
 import android.view.WindowManagerPolicy;
-import android.view.accessibility.AccessibilityEvent;
 
 /**
  * Intercepts key events and forwards them to accessibility manager service.
  */
-public class KeyboardInterceptor implements EventStreamTransformation, Handler.Callback {
+public class KeyboardInterceptor extends BaseEventStreamTransformation implements Handler.Callback {
     private static final int MESSAGE_PROCESS_QUEUED_EVENTS = 1;
     private static final String LOG_TAG = "KeyboardInterceptor";
 
@@ -37,7 +35,6 @@
     private final WindowManagerPolicy mPolicy;
     private final Handler mHandler;
 
-    private EventStreamTransformation mNext;
     private KeyEventHolder mEventQueueStart;
     private KeyEventHolder mEventQueueEnd;
 
@@ -65,13 +62,6 @@
     }
 
     @Override
-    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
-        if (mNext != null) {
-            mNext.onMotionEvent(event, rawEvent, policyFlags);
-        }
-    }
-
-    @Override
     public void onKeyEvent(KeyEvent event, int policyFlags) {
         /*
          * Certain keys have system-level behavior that affects accessibility services.
@@ -90,29 +80,6 @@
     }
 
     @Override
-    public void onAccessibilityEvent(AccessibilityEvent event) {
-        if (mNext != null) {
-            mNext.onAccessibilityEvent(event);
-        }
-    }
-
-    @Override
-    public void setNext(EventStreamTransformation next) {
-        mNext = next;
-    }
-
-    @Override
-    public void clearEvents(int inputSource) {
-        if (mNext != null) {
-            mNext.clearEvents(inputSource);
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-    }
-
-    @Override
     public boolean handleMessage(Message msg) {
         if (msg.what != MESSAGE_PROCESS_QUEUED_EVENTS) {
             Slog.e(LOG_TAG, "Unexpected message type");
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
index d6452f8..969f5b0 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
@@ -42,14 +42,12 @@
 import android.util.TypedValue;
 import android.view.GestureDetector;
 import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.MotionEvent.PointerCoords;
 import android.view.MotionEvent.PointerProperties;
 import android.view.ScaleGestureDetector;
 import android.view.ScaleGestureDetector.OnScaleGestureListener;
 import android.view.ViewConfiguration;
-import android.view.accessibility.AccessibilityEvent;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -102,7 +100,7 @@
  * 7. The magnification scale will be persisted in settings and in the cloud.
  */
 @SuppressWarnings("WeakerAccess")
-class MagnificationGestureHandler implements EventStreamTransformation {
+class MagnificationGestureHandler extends BaseEventStreamTransformation {
     private static final String LOG_TAG = "MagnificationEventHandler";
 
     private static final boolean DEBUG_ALL = false;
@@ -110,13 +108,13 @@
     private static final boolean DEBUG_DETECTING = false || DEBUG_ALL;
     private static final boolean DEBUG_PANNING = false || DEBUG_ALL;
 
-    /** @see #handleMotionEventStateDelegating */
+    /** @see DelegatingState */
     @VisibleForTesting static final int STATE_DELEGATING = 1;
-    /** @see DetectingStateHandler */
+    /** @see DetectingState */
     @VisibleForTesting static final int STATE_DETECTING = 2;
-    /** @see ViewportDraggingStateHandler */
+    /** @see ViewportDraggingState */
     @VisibleForTesting static final int STATE_VIEWPORT_DRAGGING = 3;
-    /** @see PanningScalingStateHandler */
+    /** @see PanningScalingState */
     @VisibleForTesting static final int STATE_PANNING_SCALING = 4;
 
     private static final float MIN_SCALE = 2.0f;
@@ -124,9 +122,10 @@
 
     @VisibleForTesting final MagnificationController mMagnificationController;
 
-    @VisibleForTesting final DetectingStateHandler mDetectingStateHandler;
-    @VisibleForTesting final PanningScalingStateHandler mPanningScalingStateHandler;
-    @VisibleForTesting final ViewportDraggingStateHandler mViewportDraggingStateHandler;
+    @VisibleForTesting final DelegatingState mDelegatingState;
+    @VisibleForTesting final DetectingState mDetectingState;
+    @VisibleForTesting final PanningScalingState mPanningScalingState;
+    @VisibleForTesting final ViewportDraggingState mViewportDraggingState;
 
     private final ScreenStateReceiver mScreenStateReceiver;
 
@@ -138,21 +137,12 @@
     final boolean mDetectTripleTap;
 
     /**
-     * Whether {@link #mShortcutTriggered shortcut} is enabled
+     * Whether {@link DetectingState#mShortcutTriggered shortcut} is enabled
      */
     final boolean mDetectShortcutTrigger;
 
-    EventStreamTransformation mNext;
-
-    @VisibleForTesting int mCurrentState;
-    @VisibleForTesting int mPreviousState;
-
-    @VisibleForTesting boolean mShortcutTriggered;
-
-    /**
-     * Time of last {@link MotionEvent#ACTION_DOWN} while in {@link #STATE_DELEGATING}
-     */
-    long mDelegatingStateDownTime;
+    @VisibleForTesting State mCurrentState;
+    @VisibleForTesting State mPreviousState;
 
     private PointerCoords[] mTempPointerCoords;
     private PointerProperties[] mTempPointerProperties;
@@ -174,10 +164,10 @@
             boolean detectShortcutTrigger) {
         mMagnificationController = magnificationController;
 
-        mDetectingStateHandler = new DetectingStateHandler(context);
-        mViewportDraggingStateHandler = new ViewportDraggingStateHandler();
-        mPanningScalingStateHandler =
-                new PanningScalingStateHandler(context);
+        mDelegatingState = new DelegatingState();
+        mDetectingState = new DetectingState(context);
+        mViewportDraggingState = new ViewportDraggingState();
+        mPanningScalingState = new PanningScalingState(context);
 
         mDetectTripleTap = detectTripleTap;
         mDetectShortcutTrigger = detectShortcutTrigger;
@@ -189,7 +179,7 @@
             mScreenStateReceiver = null;
         }
 
-        transitionTo(STATE_DETECTING);
+        transitionTo(mDetectingState);
     }
 
     @Override
@@ -199,52 +189,17 @@
             dispatchTransformedEvent(event, rawEvent, policyFlags);
             return;
         }
-        // Local copy to avoid dispatching the same event to more than one state handler
-        // in case mPanningScalingStateHandler changes mCurrentState
-        int currentState = mCurrentState;
-        mPanningScalingStateHandler.onMotionEvent(event, rawEvent, policyFlags);
-        switch (currentState) {
-            case STATE_DELEGATING: {
-                handleMotionEventStateDelegating(event, rawEvent, policyFlags);
-            }
-            break;
-            case STATE_DETECTING: {
-                mDetectingStateHandler.onMotionEvent(event, rawEvent, policyFlags);
-            }
-            break;
-            case STATE_VIEWPORT_DRAGGING: {
-                mViewportDraggingStateHandler.onMotionEvent(event, rawEvent, policyFlags);
-            }
-            break;
-            case STATE_PANNING_SCALING: {
-                // mPanningScalingStateHandler handles events only
-                // if this is the current state since it uses ScaleGestureDetector
-                // and a GestureDetector which need well formed event stream.
-            }
-            break;
-            default: {
-                throw new IllegalStateException("Unknown state: " + currentState);
-            }
-        }
+
+        handleEventWith(mCurrentState, event, rawEvent, policyFlags);
     }
 
-    @Override
-    public void onKeyEvent(KeyEvent event, int policyFlags) {
-        if (mNext != null) {
-            mNext.onKeyEvent(event, policyFlags);
-        }
-    }
+    private void handleEventWith(State stateHandler,
+            MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+        // To keep InputEventConsistencyVerifiers within GestureDetectors happy
+        mPanningScalingState.mScrollGestureDetector.onTouchEvent(event);
+        mPanningScalingState.mScaleGestureDetector.onTouchEvent(event);
 
-    @Override
-    public void onAccessibilityEvent(AccessibilityEvent event) {
-        if (mNext != null) {
-            mNext.onAccessibilityEvent(event);
-        }
-    }
-
-    @Override
-    public void setNext(EventStreamTransformation next) {
-        mNext = next;
+        stateHandler.onMotionEvent(event, rawEvent, policyFlags);
     }
 
     @Override
@@ -253,9 +208,7 @@
             clearAndTransitionToStateDetecting();
         }
 
-        if (mNext != null) {
-            mNext.clearEvents(inputSource);
-        }
+        super.clearEvents(inputSource);
     }
 
     @Override
@@ -272,60 +225,20 @@
             if (wasMagnifying) {
                 clearAndTransitionToStateDetecting();
             } else {
-                toggleShortcutTriggered();
+                mDetectingState.toggleShortcutTriggered();
             }
         }
     }
 
-    private void toggleShortcutTriggered() {
-        setShortcutTriggered(!mShortcutTriggered);
-    }
-
-    private void setShortcutTriggered(boolean state) {
-        if (mShortcutTriggered == state) {
-            return;
-        }
-
-        mShortcutTriggered = state;
-        mMagnificationController.setForceShowMagnifiableBounds(state);
-    }
-
     void clearAndTransitionToStateDetecting() {
-        setShortcutTriggered(false);
-        mCurrentState = STATE_DETECTING;
-        mDetectingStateHandler.clear();
-        mViewportDraggingStateHandler.clear();
-        mPanningScalingStateHandler.clear();
-    }
-
-    private void handleMotionEventStateDelegating(MotionEvent event,
-            MotionEvent rawEvent, int policyFlags) {
-        if (event.getActionMasked() == ACTION_UP) {
-            transitionTo(STATE_DETECTING);
-        }
-        delegateEvent(event, rawEvent, policyFlags);
-    }
-
-    void delegateEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
-        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            mDelegatingStateDownTime = event.getDownTime();
-        }
-        if (mNext != null) {
-            // We cache some events to see if the user wants to trigger magnification.
-            // If no magnification is triggered we inject these events with adjusted
-            // time and down time to prevent subsequent transformations being confused
-            // by stale events. After the cached events, which always have a down, are
-            // injected we need to also update the down time of all subsequent non cached
-            // events. All delegated events cached and non-cached are delivered here.
-            event.setDownTime(mDelegatingStateDownTime);
-            dispatchTransformedEvent(event, rawEvent, policyFlags);
-        }
+        mCurrentState = mDelegatingState;
+        mDetectingState.clear();
+        mViewportDraggingState.clear();
+        mPanningScalingState.clear();
     }
 
     private void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
             int policyFlags) {
-        if (mNext == null) return; // Nowhere to dispatch to
-
         // If the touchscreen event is within the magnified portion of the screen we have
         // to change its location to be where the user thinks he is poking the
         // UI which may have been magnified and panned.
@@ -351,7 +264,7 @@
                     coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(),
                     event.getFlags());
         }
-        mNext.onMotionEvent(event, rawEvent, policyFlags);
+        super.onMotionEvent(event, rawEvent, policyFlags);
     }
 
     private PointerCoords[] getTempPointerCoordsWithMinSize(int size) {
@@ -386,9 +299,10 @@
         return mTempPointerProperties;
     }
 
-    private void transitionTo(int state) {
+    private void transitionTo(State state) {
         if (DEBUG_STATE_TRANSITIONS) {
-            Slog.i(LOG_TAG, (stateToString(mCurrentState) + " -> " + stateToString(state)
+            Slog.i(LOG_TAG,
+                    (State.nameOf(mCurrentState) + " -> " + State.nameOf(state)
                     + " at " + asList(copyOfRange(new RuntimeException().getStackTrace(), 1, 5)))
                     .replace(getClass().getName(), ""));
         }
@@ -396,40 +310,42 @@
         mCurrentState = state;
     }
 
-    private static String stateToString(int state) {
-        switch (state) {
-            case STATE_DELEGATING: return "STATE_DELEGATING";
-            case STATE_DETECTING: return "STATE_DETECTING";
-            case STATE_VIEWPORT_DRAGGING: return "STATE_VIEWPORT_DRAGGING";
-            case STATE_PANNING_SCALING: return "STATE_PANNING_SCALING";
-            case 0: return "0";
-            default: throw new IllegalArgumentException("Unknown state: " + state);
-        }
-    }
-
-    private interface MotionEventHandler {
-
+    interface State {
         void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags);
 
-        void clear();
+        default void clear() {}
+
+        default String name() {
+            return getClass().getSimpleName();
+        }
+
+        static String nameOf(@Nullable State s) {
+            return s != null ? s.name() : "null";
+        }
     }
 
     /**
      * This class determines if the user is performing a scale or pan gesture.
      *
+     * Unlike when {@link ViewportDraggingState dragging the viewport}, in panning mode the viewport
+     * moves in the same direction as the fingers, and allows to easily and precisely scale the
+     * magnification level.
+     * This makes it the preferred mode for one-off adjustments, due to its precision and ease of
+     * triggering.
+     *
      * @see #STATE_PANNING_SCALING
      */
-    final class PanningScalingStateHandler extends SimpleOnGestureListener
-            implements OnScaleGestureListener, MotionEventHandler {
+    final class PanningScalingState extends SimpleOnGestureListener
+            implements OnScaleGestureListener, State {
 
         private final ScaleGestureDetector mScaleGestureDetector;
-        private final GestureDetector mGestureDetector;
+        private final GestureDetector mScrollGestureDetector;
         final float mScalingThreshold;
 
         float mInitialScaleFactor = -1;
         boolean mScaling;
 
-        public PanningScalingStateHandler(Context context) {
+        public PanningScalingState(Context context) {
             final TypedValue scaleValue = new TypedValue();
             context.getResources().getValue(
                     com.android.internal.R.dimen.config_screen_magnification_scaling_threshold,
@@ -437,35 +353,27 @@
             mScalingThreshold = scaleValue.getFloat();
             mScaleGestureDetector = new ScaleGestureDetector(context, this);
             mScaleGestureDetector.setQuickScaleEnabled(false);
-            mGestureDetector = new GestureDetector(context, this);
+            mScrollGestureDetector = new GestureDetector(context, this);
         }
 
         @Override
         public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
-            // Dispatches #onScaleBegin, #onScale, #onScaleEnd
-            mScaleGestureDetector.onTouchEvent(event);
-            // Dispatches #onScroll
-            mGestureDetector.onTouchEvent(event);
-
-            if (mCurrentState != STATE_PANNING_SCALING) {
-                return;
-            }
-
             int action = event.getActionMasked();
+
             if (action == ACTION_POINTER_UP
                     && event.getPointerCount() == 2 // includes the pointer currently being released
-                    && mPreviousState == STATE_VIEWPORT_DRAGGING) {
+                    && mPreviousState == mViewportDraggingState) {
 
-                persistScaleAndTransitionTo(STATE_VIEWPORT_DRAGGING);
+                persistScaleAndTransitionTo(mViewportDraggingState);
 
             } else if (action == ACTION_UP) {
 
-                persistScaleAndTransitionTo(STATE_DETECTING);
+                persistScaleAndTransitionTo(mDetectingState);
 
             }
         }
 
-        public void persistScaleAndTransitionTo(int state) {
+        public void persistScaleAndTransitionTo(State state) {
             mMagnificationController.persistScale();
             clear();
             transitionTo(state);
@@ -474,7 +382,7 @@
         @Override
         public boolean onScroll(MotionEvent first, MotionEvent second,
                 float distanceX, float distanceY) {
-            if (mCurrentState != STATE_PANNING_SCALING) {
+            if (mCurrentState != mPanningScalingState) {
                 return true;
             }
             if (DEBUG_PANNING) {
@@ -483,7 +391,7 @@
             }
             mMagnificationController.offsetMagnifiedRegion(distanceX, distanceY,
                     AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
-            return true;
+            return /* event consumed: */ true;
         }
 
         @Override
@@ -525,12 +433,12 @@
             final float pivotY = detector.getFocusY();
             mMagnificationController.setScale(scale, pivotX, pivotY, false,
                     AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
-            return true;
+            return /* handled: */ true;
         }
 
         @Override
         public boolean onScaleBegin(ScaleGestureDetector detector) {
-            return (mCurrentState == STATE_PANNING_SCALING);
+            return /* continue recognizing: */ (mCurrentState == mPanningScalingState);
         }
 
         @Override
@@ -546,7 +454,7 @@
 
         @Override
         public String toString() {
-            return "MagnifiedContentInteractionStateHandler{" +
+            return "PanningScalingState{" +
                     "mInitialScaleFactor=" + mInitialScaleFactor +
                     ", mScaling=" + mScaling +
                     '}';
@@ -558,9 +466,13 @@
      * determined that the user is performing a single-finger drag of the
      * magnification viewport.
      *
+     * Unlike when {@link PanningScalingState panning}, the viewport moves in the opposite direction
+     * of the finger, and any part of the screen is reachable without lifting the finger.
+     * This makes it the preferable mode for tasks like reading text spanning full screen width.
+     *
      * @see #STATE_VIEWPORT_DRAGGING
      */
-    final class ViewportDraggingStateHandler implements MotionEventHandler {
+    final class ViewportDraggingState implements State {
 
         /** Whether to disable zoom after dragging ends */
         boolean mZoomedInBeforeDrag;
@@ -572,7 +484,7 @@
             switch (action) {
                 case ACTION_POINTER_DOWN: {
                     clear();
-                    transitionTo(STATE_PANNING_SCALING);
+                    transitionTo(mPanningScalingState);
                 }
                 break;
                 case ACTION_MOVE: {
@@ -594,7 +506,7 @@
                 case ACTION_UP: {
                     if (!mZoomedInBeforeDrag) zoomOff();
                     clear();
-                    transitionTo(STATE_DETECTING);
+                    transitionTo(mDetectingState);
                 }
                 break;
 
@@ -613,25 +525,53 @@
 
         @Override
         public String toString() {
-            return "ViewportDraggingStateHandler{" +
+            return "ViewportDraggingState{" +
                     "mZoomedInBeforeDrag=" + mZoomedInBeforeDrag +
                     ", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion +
                     '}';
         }
     }
 
+    final class DelegatingState implements State {
+        /**
+         * Time of last {@link MotionEvent#ACTION_DOWN} while in {@link #STATE_DELEGATING}
+         */
+        public long mLastDelegatedDownEventTime;
+
+        @Override
+        public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+            if (event.getActionMasked() == ACTION_UP) {
+                transitionTo(mDetectingState);
+            }
+
+            if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+                mLastDelegatedDownEventTime = event.getDownTime();
+            }
+            if (getNext() != null) {
+                // We cache some events to see if the user wants to trigger magnification.
+                // If no magnification is triggered we inject these events with adjusted
+                // time and down time to prevent subsequent transformations being confused
+                // by stale events. After the cached events, which always have a down, are
+                // injected we need to also update the down time of all subsequent non cached
+                // events. All delegated events cached and non-cached are delivered here.
+                event.setDownTime(mLastDelegatedDownEventTime);
+                dispatchTransformedEvent(event, rawEvent, policyFlags);
+            }
+        }
+    }
+
     /**
      * This class handles motion events when the event dispatch has not yet
      * determined what the user is doing. It watches for various tap events.
      *
      * @see #STATE_DETECTING
      */
-    final class DetectingStateHandler implements MotionEventHandler, Handler.Callback {
+    final class DetectingState implements State, Handler.Callback {
 
         private static final int MESSAGE_ON_TRIPLE_TAP_AND_HOLD = 1;
         private static final int MESSAGE_TRANSITION_TO_DELEGATING_STATE = 2;
 
-        final int mLongTapMinDelay = ViewConfiguration.getJumpTapTimeout();
+        final int mLongTapMinDelay;
         final int mSwipeMinDistance;
         final int mMultiTapMaxDelay;
         final int mMultiTapMaxDistance;
@@ -642,9 +582,12 @@
         private MotionEvent mLastUp;
         private MotionEvent mPreLastUp;
 
+        @VisibleForTesting boolean mShortcutTriggered;
+
         Handler mHandler = new Handler(this);
 
-        public DetectingStateHandler(Context context) {
+        public DetectingState(Context context) {
+            mLongTapMinDelay = ViewConfiguration.getLongPressTimeout();
             mMultiTapMaxDelay = ViewConfiguration.getDoubleTapTimeout()
                     + context.getResources().getInteger(
                     com.android.internal.R.integer.config_screen_magnification_multi_tap_adjustment);
@@ -661,7 +604,7 @@
                 }
                 break;
                 case MESSAGE_TRANSITION_TO_DELEGATING_STATE: {
-                    transitionToDelegatingState(/* andClear */ true);
+                    transitionToDelegatingStateAndClear();
                 }
                 break;
                 default: {
@@ -682,12 +625,12 @@
                     if (!mMagnificationController.magnificationRegionContains(
                             event.getX(), event.getY())) {
 
-                        transitionToDelegatingState(/* andClear */ !mShortcutTriggered);
+                        transitionToDelegatingStateAndClear();
 
                     } else if (isMultiTapTriggered(2 /* taps */)) {
 
                         // 3tap and hold
-                        delayedTransitionToDraggingState(event);
+                        afterLongTapTimeoutTransitionToDraggingState(event);
 
                     } else if (mDetectTripleTap
                             // If magnified, delay an ACTION_DOWN for mMultiTapMaxDelay
@@ -695,21 +638,21 @@
                             // STATE_PANNING_SCALING(triggerable with ACTION_POINTER_DOWN)
                             || mMagnificationController.isMagnifying()) {
 
-                        delayedTransitionToDelegatingState();
+                        afterMultiTapTimeoutTransitionToDelegatingState();
 
                     } else {
 
                         // Delegate pending events without delay
-                        transitionToDelegatingState(/* andClear */ true);
+                        transitionToDelegatingStateAndClear();
                     }
                 }
                 break;
                 case ACTION_POINTER_DOWN: {
                     if (mMagnificationController.isMagnifying()) {
-                        transitionTo(STATE_PANNING_SCALING);
+                        transitionTo(mPanningScalingState);
                         clear();
                     } else {
-                        transitionToDelegatingState(/* andClear */ true);
+                        transitionToDelegatingStateAndClear();
                     }
                 }
                 break;
@@ -722,7 +665,7 @@
                             && !isMultiTapTriggered(2 /* taps */)) {
 
                         // Swipe detected - delegate skipping timeout
-                        transitionToDelegatingState(/* andClear */ true);
+                        transitionToDelegatingStateAndClear();
                     }
                 }
                 break;
@@ -733,7 +676,7 @@
                     if (!mMagnificationController.magnificationRegionContains(
                             event.getX(), event.getY())) {
 
-                        transitionToDelegatingState(/* andClear */ !mShortcutTriggered);
+                        transitionToDelegatingStateAndClear();
 
                     } else if (isMultiTapTriggered(3 /* taps */)) {
 
@@ -742,12 +685,11 @@
                     } else if (
                             // Possible to be false on: 3tap&drag -> scale -> PTR_UP -> UP
                             isFingerDown()
-                                //TODO long tap should never happen here
-                            && (timeBetween(mLastDown, /* mLastUp */ event) >= mLongTapMinDelay)
-                                    || distance(mLastDown, /* mLastUp */ event)
-                                            >= mSwipeMinDistance) {
+                            //TODO long tap should never happen here
+                            && ((timeBetween(mLastDown, mLastUp) >= mLongTapMinDelay)
+                                    || (distance(mLastDown, mLastUp) >= mSwipeMinDistance))) {
 
-                        transitionToDelegatingState(/* andClear */ true);
+                        transitionToDelegatingStateAndClear();
 
                     }
                 }
@@ -796,14 +738,14 @@
         }
 
         /** -> {@link #STATE_DELEGATING} */
-        public void delayedTransitionToDelegatingState() {
+        public void afterMultiTapTimeoutTransitionToDelegatingState() {
             mHandler.sendEmptyMessageDelayed(
                     MESSAGE_TRANSITION_TO_DELEGATING_STATE,
                     mMultiTapMaxDelay);
         }
 
         /** -> {@link #STATE_VIEWPORT_DRAGGING} */
-        public void delayedTransitionToDraggingState(MotionEvent event) {
+        public void afterLongTapTimeoutTransitionToDraggingState(MotionEvent event) {
             mHandler.sendMessageDelayed(
                     mHandler.obtainMessage(MESSAGE_ON_TRIPLE_TAP_AND_HOLD, event),
                     ViewConfiguration.getLongPressTimeout());
@@ -846,11 +788,7 @@
                 MotionEventInfo info = mDelayedEventQueue;
                 mDelayedEventQueue = info.mNext;
 
-                // Because MagnifiedInteractionStateHandler requires well-formed event stream
-                mPanningScalingStateHandler.onMotionEvent(
-                        info.event, info.rawEvent, info.policyFlags);
-
-                delegateEvent(info.event, info.rawEvent, info.policyFlags);
+                handleEventWith(mDelegatingState, info.event, info.rawEvent, info.policyFlags);
 
                 info.recycle();
             }
@@ -868,10 +806,10 @@
             mLastUp = null;
         }
 
-        void transitionToDelegatingState(boolean andClear) {
-            transitionTo(STATE_DELEGATING);
+        void transitionToDelegatingStateAndClear() {
+            transitionTo(mDelegatingState);
             sendDelayedMotionEvents();
-            if (andClear) clear();
+            clear();
         }
 
         private void onTripleTap(MotionEvent up) {
@@ -895,21 +833,35 @@
             if (DEBUG_DETECTING) Slog.i(LOG_TAG, "onTripleTapAndHold()");
             clear();
 
-            mViewportDraggingStateHandler.mZoomedInBeforeDrag =
+            mViewportDraggingState.mZoomedInBeforeDrag =
                     mMagnificationController.isMagnifying();
 
             zoomOn(down.getX(), down.getY());
 
-            transitionTo(STATE_VIEWPORT_DRAGGING);
+            transitionTo(mViewportDraggingState);
         }
 
         @Override
         public String toString() {
-            return "DetectingStateHandler{" +
+            return "DetectingState{" +
                     "tapCount()=" + tapCount() +
+                    ", mShortcutTriggered=" + mShortcutTriggered +
                     ", mDelayedEventQueue=" + MotionEventInfo.toString(mDelayedEventQueue) +
                     '}';
         }
+
+        void toggleShortcutTriggered() {
+            setShortcutTriggered(!mShortcutTriggered);
+        }
+
+        void setShortcutTriggered(boolean state) {
+            if (mShortcutTriggered == state) {
+                return;
+            }
+
+            mShortcutTriggered = state;
+            mMagnificationController.setForceShowMagnifiableBounds(state);
+        }
     }
 
     private void zoomOn(float centerX, float centerY) {
@@ -935,16 +887,15 @@
 
     @Override
     public String toString() {
-        return "MagnificationGestureHandler{" +
-                "mDetectingStateHandler=" + mDetectingStateHandler +
-                ", mMagnifiedInteractionStateHandler=" + mPanningScalingStateHandler +
-                ", mViewportDraggingStateHandler=" + mViewportDraggingStateHandler +
+        return "MagnificationGesture{" +
+                "mDetectingState=" + mDetectingState +
+                ", mDelegatingState=" + mDelegatingState +
+                ", mMagnifiedInteractionState=" + mPanningScalingState +
+                ", mViewportDraggingState=" + mViewportDraggingState +
                 ", mDetectTripleTap=" + mDetectTripleTap +
                 ", mDetectShortcutTrigger=" + mDetectShortcutTrigger +
-                ", mCurrentState=" + stateToString(mCurrentState) +
-                ", mPreviousState=" + stateToString(mPreviousState) +
-                ", mShortcutTriggered=" + mShortcutTriggered +
-                ", mDelegatingStateDownTime=" + mDelegatingStateDownTime +
+                ", mCurrentState=" + State.nameOf(mCurrentState) +
+                ", mPreviousState=" + State.nameOf(mPreviousState) +
                 ", mMagnificationController=" + mMagnificationController +
                 '}';
     }
@@ -1051,7 +1002,7 @@
 
         @Override
         public void onReceive(Context context, Intent intent) {
-            mGestureHandler.setShortcutTriggered(false);
+            mGestureHandler.mDetectingState.setShortcutTriggered(false);
         }
     }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
index 48041ad..7925510 100644
--- a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
+++ b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
@@ -30,10 +30,9 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.view.InputDevice;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.WindowManagerPolicy;
-import android.view.accessibility.AccessibilityEvent;
+
 import com.android.internal.os.SomeArgs;
 
 import java.util.ArrayList;
@@ -45,7 +44,7 @@
  * <p>
  * All methods except {@code injectEvents} must be called only from the main thread.
  */
-public class MotionEventInjector implements EventStreamTransformation, Handler.Callback {
+public class MotionEventInjector extends BaseEventStreamTransformation implements Handler.Callback {
     private static final String LOG_TAG = "MotionEventInjector";
     private static final int MESSAGE_SEND_MOTION_EVENT = 1;
     private static final int MESSAGE_INJECT_EVENTS = 2;
@@ -68,7 +67,6 @@
     private final Handler mHandler;
     private final SparseArray<Boolean> mOpenGesturesInProgress = new SparseArray<>();
 
-    private EventStreamTransformation mNext;
     private IAccessibilityServiceClient mServiceInterfaceForCurrentGesture;
     private IntArray mSequencesInProgress = new IntArray(5);
     private boolean mIsDestroyed = false;
@@ -117,25 +115,6 @@
     }
 
     @Override
-    public void onKeyEvent(KeyEvent event, int policyFlags) {
-        if (mNext != null) {
-            mNext.onKeyEvent(event, policyFlags);
-        }
-    }
-
-    @Override
-    public void onAccessibilityEvent(AccessibilityEvent event) {
-        if (mNext != null) {
-            mNext.onAccessibilityEvent(event);
-        }
-    }
-
-    @Override
-    public void setNext(EventStreamTransformation next) {
-        mNext = next;
-    }
-
-    @Override
     public void clearEvents(int inputSource) {
         /*
          * Reset state for motion events passing through so we won't send a cancel event for
@@ -187,7 +166,7 @@
             return;
         }
 
-        if (mNext == null) {
+        if (getNext() == null) {
             notifyService(serviceInterface, sequence, false);
             return;
         }
@@ -292,8 +271,8 @@
 
     private void sendMotionEventToNext(MotionEvent event, MotionEvent rawEvent,
             int policyFlags) {
-        if (mNext != null) {
-            mNext.onMotionEvent(event, rawEvent, policyFlags);
+        if (getNext() != null) {
+            super.onMotionEvent(event, rawEvent, policyFlags);
             if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
                 mOpenGesturesInProgress.put(event.getSource(), true);
             }
@@ -305,7 +284,7 @@
     }
 
     private void cancelAnyGestureInProgress(int source) {
-        if ((mNext != null) && mOpenGesturesInProgress.get(source, false)) {
+        if ((getNext() != null) && mOpenGesturesInProgress.get(source, false)) {
             long now = SystemClock.uptimeMillis();
             MotionEvent cancelEvent =
                     obtainMotionEvent(now, now, MotionEvent.ACTION_CANCEL, getLastTouchPoints(), 1);
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index e380f2c..a32686d 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -55,7 +55,8 @@
  *
  * @hide
  */
-class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDetector.Listener {
+class TouchExplorer extends BaseEventStreamTransformation
+        implements AccessibilityGestureDetector.Listener {
 
     private static final boolean DEBUG = false;
 
@@ -131,9 +132,6 @@
     // the two dragging pointers as opposed to use the location of the primary one.
     private final int mScaledMinPointerDistanceToUseMiddleLocation;
 
-    // The handler to which to delegate events.
-    private EventStreamTransformation mNext;
-
     // Helper class to track received pointers.
     private final ReceivedPointerTracker mReceivedPointerTracker;
 
@@ -198,9 +196,7 @@
         if (inputSource == InputDevice.SOURCE_TOUCHSCREEN) {
             clear();
         }
-        if (mNext != null) {
-            mNext.clearEvents(inputSource);
-        }
+        super.clearEvents(inputSource);
     }
 
     @Override
@@ -258,16 +254,9 @@
     }
 
     @Override
-    public void setNext(EventStreamTransformation next) {
-        mNext = next;
-    }
-
-    @Override
     public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
         if (!event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)) {
-            if (mNext != null) {
-                mNext.onMotionEvent(event, rawEvent, policyFlags);
-            }
+            super.onMotionEvent(event, rawEvent, policyFlags);
             return;
         }
 
@@ -311,13 +300,6 @@
     }
 
     @Override
-    public void onKeyEvent(KeyEvent event, int policyFlags) {
-        if (mNext != null) {
-            mNext.onKeyEvent(event, policyFlags);
-        }
-    }
-
-    @Override
     public void onAccessibilityEvent(AccessibilityEvent event) {
         final int eventType = event.getEventType();
 
@@ -353,9 +335,7 @@
                 mLastTouchedWindowId = event.getWindowId();
             } break;
         }
-        if (mNext != null) {
-            mNext.onAccessibilityEvent(event);
-        }
+        super.onAccessibilityEvent(event);
     }
 
     @Override
@@ -969,12 +949,10 @@
 
         // Make sure that the user will see the event.
         policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER;
-        if (mNext != null) {
-            // TODO: For now pass null for the raw event since the touch
-            //       explorer is the last event transformation and it does
-            //       not care about the raw event.
-            mNext.onMotionEvent(event, null, policyFlags);
-        }
+        // TODO: For now pass null for the raw event since the touch
+        //       explorer is the last event transformation and it does
+        //       not care about the raw event.
+        super.onMotionEvent(event, null, policyFlags);
 
         mInjectedPointerTracker.onMotionEvent(event);
 
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index a6aaaa67..51afada 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -71,7 +71,6 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.StorageManager;
 import android.service.appwidget.AppWidgetServiceDumpProto;
 import android.service.appwidget.WidgetProto;
 import android.text.TextUtils;
@@ -159,7 +158,9 @@
     // Bump if the stored widgets need to be upgraded.
     private static final int CURRENT_VERSION = 1;
 
-    private static final AtomicLong REQUEST_COUNTER = new AtomicLong();
+    // Every widget update request is associated which an increasing sequence number. This is
+    // used to verify which request has successfully been received by the host.
+    private static final AtomicLong UPDATE_COUNTER = new AtomicLong();
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -814,9 +815,9 @@
             Host host = lookupOrAddHostLocked(id);
             host.callbacks = callbacks;
 
+            long updateSequenceNo = UPDATE_COUNTER.incrementAndGet();
             int N = appWidgetIds.length;
             ArrayList<PendingHostUpdate> outUpdates = new ArrayList<>(N);
-
             LongSparseArray<PendingHostUpdate> updatesMap = new LongSparseArray<>();
             for (int i = 0; i < N; i++) {
                 if (host.getPendingUpdatesForId(appWidgetIds[i], updatesMap)) {
@@ -828,6 +829,8 @@
                     }
                 }
             }
+            // Reset the update counter once all the updates have been calculated
+            host.lastWidgetUpdateSequenceNo = updateSequenceNo;
             return new ParceledListSlice<>(outUpdates);
         }
     }
@@ -1914,9 +1917,9 @@
             // method with a wrong id. In that case, ignore the call.
             return;
         }
-        long requestId = REQUEST_COUNTER.incrementAndGet();
+        long requestId = UPDATE_COUNTER.incrementAndGet();
         if (widget != null) {
-            widget.updateRequestIds.put(viewId, requestId);
+            widget.updateSequenceNos.put(viewId, requestId);
         }
         if (widget == null || widget.host == null || widget.host.zombie
                 || widget.host.callbacks == null || widget.provider == null
@@ -1941,7 +1944,7 @@
             int appWidgetId, int viewId, long requestId) {
         try {
             callbacks.viewDataChanged(appWidgetId, viewId);
-            host.lastWidgetUpdateRequestId = requestId;
+            host.lastWidgetUpdateSequenceNo = requestId;
         } catch (RemoteException re) {
             // It failed; remove the callback. No need to prune because
             // we know that this host is still referenced by this instance.
@@ -1988,9 +1991,9 @@
     }
 
     private void scheduleNotifyUpdateAppWidgetLocked(Widget widget, RemoteViews updateViews) {
-        long requestId = REQUEST_COUNTER.incrementAndGet();
+        long requestId = UPDATE_COUNTER.incrementAndGet();
         if (widget != null) {
-            widget.updateRequestIds.put(ID_VIEWS_UPDATE, requestId);
+            widget.updateSequenceNos.put(ID_VIEWS_UPDATE, requestId);
         }
         if (widget == null || widget.provider == null || widget.provider.zombie
                 || widget.host.callbacks == null || widget.host.zombie) {
@@ -2013,7 +2016,7 @@
             int appWidgetId, RemoteViews views, long requestId) {
         try {
             callbacks.updateAppWidget(appWidgetId, views);
-            host.lastWidgetUpdateRequestId = requestId;
+            host.lastWidgetUpdateSequenceNo = requestId;
         } catch (RemoteException re) {
             synchronized (mLock) {
                 Slog.e(TAG, "Widget host dead: " + host.id, re);
@@ -2023,11 +2026,11 @@
     }
 
     private void scheduleNotifyProviderChangedLocked(Widget widget) {
-        long requestId = REQUEST_COUNTER.incrementAndGet();
+        long requestId = UPDATE_COUNTER.incrementAndGet();
         if (widget != null) {
             // When the provider changes, reset everything else.
-            widget.updateRequestIds.clear();
-            widget.updateRequestIds.append(ID_PROVIDER_CHANGED, requestId);
+            widget.updateSequenceNos.clear();
+            widget.updateSequenceNos.append(ID_PROVIDER_CHANGED, requestId);
         }
         if (widget == null || widget.provider == null || widget.provider.zombie
                 || widget.host.callbacks == null || widget.host.zombie) {
@@ -2050,7 +2053,7 @@
             int appWidgetId, AppWidgetProviderInfo info, long requestId) {
         try {
             callbacks.providerChanged(appWidgetId, info);
-            host.lastWidgetUpdateRequestId = requestId;
+            host.lastWidgetUpdateSequenceNo = requestId;
         } catch (RemoteException re) {
             synchronized (mLock){
                 Slog.e(TAG, "Widget host dead: " + host.id, re);
@@ -3887,7 +3890,11 @@
         boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
 
         int tag = TAG_UNDEFINED; // for use while saving state (the index)
-        long lastWidgetUpdateRequestId; // request id for the last update successfully sent
+        // Sequence no for the last update successfully sent. This is updated whenever a
+        // widget update is successfully sent to the host callbacks. As all new/undelivered updates
+        // will have sequenceNo greater than this, all those updates will be sent when the host
+        // callbacks are attached again.
+        long lastWidgetUpdateSequenceNo;
 
         public int getUserId() {
             return UserHandle.getUserId(id.uid);
@@ -3914,18 +3921,18 @@
          */
         public boolean getPendingUpdatesForId(int appWidgetId,
                 LongSparseArray<PendingHostUpdate> outUpdates) {
-            long updateRequestId = lastWidgetUpdateRequestId;
+            long updateSequenceNo = lastWidgetUpdateSequenceNo;
             int N = widgets.size();
             for (int i = 0; i < N; i++) {
                 Widget widget = widgets.get(i);
                 if (widget.appWidgetId == appWidgetId) {
                     outUpdates.clear();
-                    for (int j = widget.updateRequestIds.size() - 1; j >= 0; j--) {
-                        long requestId = widget.updateRequestIds.valueAt(j);
-                        if (requestId <= updateRequestId) {
+                    for (int j = widget.updateSequenceNos.size() - 1; j >= 0; j--) {
+                        long requestId = widget.updateSequenceNos.valueAt(j);
+                        if (requestId <= updateSequenceNo) {
                             continue;
                         }
-                        int id = widget.updateRequestIds.keyAt(j);
+                        int id = widget.updateSequenceNos.keyAt(j);
                         final PendingHostUpdate update;
                         switch (id) {
                             case ID_PROVIDER_CHANGED:
@@ -4021,8 +4028,8 @@
         RemoteViews maskedViews;
         Bundle options;
         Host host;
-        // Request ids for various operations
-        SparseLongArray updateRequestIds = new SparseLongArray(2);
+        // Map of request type to updateSequenceNo.
+        SparseLongArray updateSequenceNos = new SparseLongArray(2);
 
         @Override
         public String toString() {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 862070a..880f236 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -216,9 +216,12 @@
                 serviceComponent = ComponentName.unflattenFromString(componentName);
                 serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
                         0, mUserId);
+                if (serviceInfo == null) {
+                    Slog.e(TAG, "Bad AutofillService name: " + componentName);
+                }
             } catch (RuntimeException | RemoteException e) {
-                Slog.e(TAG, "Bad autofill service name " + componentName + ": " + e);
-                return;
+                Slog.e(TAG, "Error getting service info for '" + componentName + "': " + e);
+                serviceInfo = null;
             }
         }
         try {
@@ -228,21 +231,24 @@
                 if (sDebug) Slog.d(TAG, "Set component for user " + mUserId + " as " + mInfo);
             } else {
                 mInfo = null;
-                if (sDebug) Slog.d(TAG, "Reset component for user " + mUserId);
-            }
-            final boolean isEnabled = isEnabled();
-            if (wasEnabled != isEnabled) {
-                if (!isEnabled) {
-                    final int sessionCount = mSessions.size();
-                    for (int i = sessionCount - 1; i >= 0; i--) {
-                        final Session session = mSessions.valueAt(i);
-                        session.removeSelfLocked();
-                    }
+                if (sDebug) {
+                    Slog.d(TAG, "Reset component for user " + mUserId + " (" + componentName + ")");
                 }
-                sendStateToClients(false);
             }
         } catch (Exception e) {
-            Slog.e(TAG, "Bad AutofillService '" + componentName + "': " + e);
+            Slog.e(TAG, "Bad AutofillServiceInfo for '" + componentName + "': " + e);
+            mInfo = null;
+        }
+        final boolean isEnabled = isEnabled();
+        if (wasEnabled != isEnabled) {
+            if (!isEnabled) {
+                final int sessionCount = mSessions.size();
+                for (int i = sessionCount - 1; i >= 0; i--) {
+                    final Session session = mSessions.valueAt(i);
+                    session.removeSelfLocked();
+                }
+            }
+            sendStateToClients(false);
         }
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index ed00ffe..3c12d67 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -495,7 +495,7 @@
             notifyUnavailableToClient(false);
         }
         synchronized (mLock) {
-            processResponseLocked(response, requestFlags);
+            processResponseLocked(response, null, requestFlags);
         }
 
         final LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName)
@@ -762,13 +762,21 @@
         }
 
         final Parcelable result = data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT);
-        if (sDebug) Slog.d(TAG, "setAuthenticationResultLocked(): result=" + result);
+        final Bundle newClientState = data.getBundle(AutofillManager.EXTRA_CLIENT_STATE);
+        if (sDebug) {
+            Slog.d(TAG, "setAuthenticationResultLocked(): result=" + result
+                    + ", clientState=" + newClientState);
+        }
         if (result instanceof FillResponse) {
             writeLog(MetricsEvent.AUTOFILL_AUTHENTICATED);
-            replaceResponseLocked(authenticatedResponse, (FillResponse) result);
+            replaceResponseLocked(authenticatedResponse, (FillResponse) result, newClientState);
         } else if (result instanceof Dataset) {
             if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) {
                 writeLog(MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED);
+                if (newClientState != null) {
+                    if (sDebug) Slog.d(TAG,  "Updating client state from auth dataset");
+                    mClientState = newClientState;
+                }
                 final Dataset dataset = (Dataset) result;
                 authenticatedResponse.getDatasets().set(datasetIdx, dataset);
                 autoFill(requestId, datasetIdx, dataset, false);
@@ -1491,8 +1499,14 @@
 
         ArraySet<AutofillId> trackedViews = null;
         boolean saveOnAllViewsInvisible = false;
+        boolean saveOnFinish = true;
         final SaveInfo saveInfo = response.getSaveInfo();
+        final AutofillId saveTriggerId;
         if (saveInfo != null) {
+            saveTriggerId = saveInfo.getTriggerId();
+            if (saveTriggerId != null) {
+                writeLog(MetricsEvent.AUTOFILL_EXPLICIT_SAVE_TRIGGER_DEFINITION);
+            }
             saveOnAllViewsInvisible =
                     (saveInfo.getFlags() & SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) != 0;
 
@@ -1509,6 +1523,12 @@
                     Collections.addAll(trackedViews, saveInfo.getOptionalIds());
                 }
             }
+            if ((saveInfo.getFlags() & SaveInfo.FLAG_DONT_SAVE_ON_FINISH) != 0) {
+                saveOnFinish = false;
+            }
+
+        } else {
+            saveTriggerId = null;
         }
 
         // Must also track that are part of datasets, otherwise the FillUI won't be hidden when
@@ -1533,17 +1553,18 @@
 
         try {
             if (sVerbose) {
-                Slog.v(TAG, "updateTrackedIdsLocked(): " + trackedViews + " => " + fillableIds);
+                Slog.v(TAG, "updateTrackedIdsLocked(): " + trackedViews + " => " + fillableIds
+                        + " (triggering on " + saveTriggerId + ")");
             }
             mClient.setTrackedViews(id, toArray(trackedViews), saveOnAllViewsInvisible,
-                    toArray(fillableIds));
+                    saveOnFinish, toArray(fillableIds), saveTriggerId);
         } catch (RemoteException e) {
             Slog.w(TAG, "Cannot set tracked ids", e);
         }
     }
 
     private void replaceResponseLocked(@NonNull FillResponse oldResponse,
-            @NonNull FillResponse newResponse) {
+            @NonNull FillResponse newResponse, @Nullable Bundle newClientState) {
         // Disassociate view states with the old response
         setViewStatesLocked(oldResponse, ViewState.STATE_INITIAL, true);
         // Move over the id
@@ -1551,7 +1572,7 @@
         // Replace the old response
         mResponses.put(newResponse.getRequestId(), newResponse);
         // Now process the new response
-        processResponseLocked(newResponse, 0);
+        processResponseLocked(newResponse, newClientState, 0);
     }
 
     private void processNullResponseLocked(int flags) {
@@ -1565,7 +1586,8 @@
         removeSelf();
     }
 
-    private void processResponseLocked(@NonNull FillResponse newResponse, int flags) {
+    private void processResponseLocked(@NonNull FillResponse newResponse,
+            @Nullable Bundle newClientState, int flags) {
         // Make sure we are hiding the UI which will be shown
         // only if handling the current response requires it.
         mUi.hideAll(this);
@@ -1573,14 +1595,15 @@
         final int requestId = newResponse.getRequestId();
         if (sVerbose) {
             Slog.v(TAG, "processResponseLocked(): mCurrentViewId=" + mCurrentViewId
-                    + ",flags=" + flags + ", reqId=" + requestId + ", resp=" + newResponse);
+                    + ",flags=" + flags + ", reqId=" + requestId + ", resp=" + newResponse
+                    + ",newClientState=" + newClientState);
         }
 
         if (mResponses == null) {
             mResponses = new SparseArray<>(4);
         }
         mResponses.put(requestId, newResponse);
-        mClientState = newResponse.getClientState();
+        mClientState = newClientState != null ? newClientState : newResponse.getClientState();
 
         setViewStatesLocked(newResponse, ViewState.STATE_FILLABLE, false);
         updateTrackedIdsLocked();
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index eabe21f..f9213aa 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -319,7 +319,6 @@
     boolean mProvisioned;
     boolean mAutoRestore;
     PowerManager.WakeLock mWakelock;
-    HandlerThread mHandlerThread;
     BackupHandler mBackupHandler;
     PendingIntent mRunBackupIntent, mRunInitIntent;
     BroadcastReceiver mRunBackupReceiver, mRunInitReceiver;
@@ -409,43 +408,37 @@
     // Called through the trampoline from onUnlockUser(), then we buck the work
     // off to the background thread to keep the unlock time down.
     public void unlockSystemUser() {
-        mBackupHandler.post(() -> {
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup init");
-            sInstance.initialize(UserHandle.USER_SYSTEM);
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-
-            // Migrate legacy setting
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup migrate");
-            if (!backupSettingMigrated(UserHandle.USER_SYSTEM)) {
+        // Migrate legacy setting
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup migrate");
+        if (!backupSettingMigrated(UserHandle.USER_SYSTEM)) {
+            if (DEBUG) {
+                Slog.i(TAG, "Backup enable apparently not migrated");
+            }
+            final ContentResolver r = sInstance.mContext.getContentResolver();
+            final int enableState = Settings.Secure.getIntForUser(r,
+                    Settings.Secure.BACKUP_ENABLED, -1, UserHandle.USER_SYSTEM);
+            if (enableState >= 0) {
                 if (DEBUG) {
-                    Slog.i(TAG, "Backup enable apparently not migrated");
+                    Slog.i(TAG, "Migrating enable state " + (enableState != 0));
                 }
-                final ContentResolver r = sInstance.mContext.getContentResolver();
-                final int enableState = Settings.Secure.getIntForUser(r,
-                        Settings.Secure.BACKUP_ENABLED, -1, UserHandle.USER_SYSTEM);
-                if (enableState >= 0) {
-                    if (DEBUG) {
-                        Slog.i(TAG, "Migrating enable state " + (enableState != 0));
-                    }
-                    writeBackupEnableState(enableState != 0, UserHandle.USER_SYSTEM);
-                    Settings.Secure.putStringForUser(r,
-                            Settings.Secure.BACKUP_ENABLED, null, UserHandle.USER_SYSTEM);
-                } else {
-                    if (DEBUG) {
-                        Slog.i(TAG, "Backup not yet configured; retaining null enable state");
-                    }
+                writeBackupEnableState(enableState != 0, UserHandle.USER_SYSTEM);
+                Settings.Secure.putStringForUser(r,
+                        Settings.Secure.BACKUP_ENABLED, null, UserHandle.USER_SYSTEM);
+            } else {
+                if (DEBUG) {
+                    Slog.i(TAG, "Backup not yet configured; retaining null enable state");
                 }
             }
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        }
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable");
-            try {
-                sInstance.setBackupEnabled(readBackupEnableState(UserHandle.USER_SYSTEM));
-            } catch (RemoteException e) {
-                // can't happen; it's a local object
-            }
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-        });
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable");
+        try {
+            sInstance.setBackupEnabled(readBackupEnableState(UserHandle.USER_SYSTEM));
+        } catch (RemoteException e) {
+            // can't happen; it's a local object
+        }
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
     class ProvisionedObserver extends ContentObserver {
@@ -1220,7 +1213,7 @@
 
     // ----- Main service implementation -----
 
-    public BackupManagerService(Context context, Trampoline parent) {
+    public BackupManagerService(Context context, Trampoline parent, HandlerThread backupThread) {
         mContext = context;
         mPackageManager = context.getPackageManager();
         mPackageManagerBinder = AppGlobals.getPackageManager();
@@ -1233,9 +1226,7 @@
         mBackupManagerBinder = Trampoline.asInterface(parent.asBinder());
 
         // spin up the backup/restore handler thread
-        mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND);
-        mHandlerThread.start();
-        mBackupHandler = new BackupHandler(mHandlerThread.getLooper());
+        mBackupHandler = new BackupHandler(backupThread.getLooper());
 
         // Set up our bookkeeping
         final ContentResolver resolver = context.getContentResolver();
@@ -1360,7 +1351,7 @@
         if (DEBUG) Slog.v(TAG, "Starting with transport " + currentTransport);
 
         mTransportManager = new TransportManager(context, transportWhitelist, currentTransport,
-                mTransportBoundListener, mHandlerThread.getLooper());
+                mTransportBoundListener, backupThread.getLooper());
         mTransportManager.registerAllTransports();
 
         // Now that we know about valid backup participants, parse any
diff --git a/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
index f298065..20f2369 100644
--- a/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
@@ -237,7 +237,6 @@
     private boolean mProvisioned;
     private boolean mAutoRestore;
     private PowerManager.WakeLock mWakelock;
-    private HandlerThread mHandlerThread;
     private BackupHandler mBackupHandler;
     private PendingIntent mRunBackupIntent;
     private PendingIntent mRunInitIntent;
@@ -556,43 +555,37 @@
     // Called through the trampoline from onUnlockUser(), then we buck the work
     // off to the background thread to keep the unlock time down.
     public void unlockSystemUser() {
-        mBackupHandler.post(() -> {
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup init");
-            sInstance.initialize(UserHandle.USER_SYSTEM);
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-
-            // Migrate legacy setting
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup migrate");
-            if (!backupSettingMigrated(UserHandle.USER_SYSTEM)) {
+        // Migrate legacy setting
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup migrate");
+        if (!backupSettingMigrated(UserHandle.USER_SYSTEM)) {
+            if (DEBUG) {
+                Slog.i(TAG, "Backup enable apparently not migrated");
+            }
+            final ContentResolver r = sInstance.mContext.getContentResolver();
+            final int enableState = Settings.Secure.getIntForUser(r,
+                    Settings.Secure.BACKUP_ENABLED, -1, UserHandle.USER_SYSTEM);
+            if (enableState >= 0) {
                 if (DEBUG) {
-                    Slog.i(TAG, "Backup enable apparently not migrated");
+                    Slog.i(TAG, "Migrating enable state " + (enableState != 0));
                 }
-                final ContentResolver r = sInstance.mContext.getContentResolver();
-                final int enableState = Settings.Secure.getIntForUser(r,
-                        Settings.Secure.BACKUP_ENABLED, -1, UserHandle.USER_SYSTEM);
-                if (enableState >= 0) {
-                    if (DEBUG) {
-                        Slog.i(TAG, "Migrating enable state " + (enableState != 0));
-                    }
-                    writeBackupEnableState(enableState != 0, UserHandle.USER_SYSTEM);
-                    Settings.Secure.putStringForUser(r,
-                            Settings.Secure.BACKUP_ENABLED, null, UserHandle.USER_SYSTEM);
-                } else {
-                    if (DEBUG) {
-                        Slog.i(TAG, "Backup not yet configured; retaining null enable state");
-                    }
+                writeBackupEnableState(enableState != 0, UserHandle.USER_SYSTEM);
+                Settings.Secure.putStringForUser(r,
+                        Settings.Secure.BACKUP_ENABLED, null, UserHandle.USER_SYSTEM);
+            } else {
+                if (DEBUG) {
+                    Slog.i(TAG, "Backup not yet configured; retaining null enable state");
                 }
             }
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        }
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable");
-            try {
-                sInstance.setBackupEnabled(readBackupEnableState(UserHandle.USER_SYSTEM));
-            } catch (RemoteException e) {
-                // can't happen; it's a local object
-            }
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-        });
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable");
+        try {
+            sInstance.setBackupEnabled(readBackupEnableState(UserHandle.USER_SYSTEM));
+        } catch (RemoteException e) {
+            // can't happen; it's a local object
+        }
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
     // Bookkeeping of in-flight operations for timeout etc. purposes.  The operation
@@ -729,7 +722,8 @@
 
     // ----- Main service implementation -----
 
-    public RefactoredBackupManagerService(Context context, Trampoline parent) {
+    public RefactoredBackupManagerService(Context context, Trampoline parent,
+            HandlerThread backupThread) {
         mContext = context;
         mPackageManager = context.getPackageManager();
         mPackageManagerBinder = AppGlobals.getPackageManager();
@@ -742,9 +736,7 @@
         mBackupManagerBinder = Trampoline.asInterface(parent.asBinder());
 
         // spin up the backup/restore handler thread
-        mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND);
-        mHandlerThread.start();
-        mBackupHandler = new BackupHandler(this, mHandlerThread.getLooper());
+        mBackupHandler = new BackupHandler(this, backupThread.getLooper());
 
         // Set up our bookkeeping
         final ContentResolver resolver = context.getContentResolver();
@@ -824,7 +816,7 @@
         if (DEBUG) Slog.v(TAG, "Starting with transport " + currentTransport);
 
         mTransportManager = new TransportManager(context, transportWhitelist, currentTransport,
-                mTransportBoundListener, mHandlerThread.getLooper());
+                mTransportBoundListener, backupThread.getLooper());
         mTransportManager.registerAllTransports();
 
         // Now that we know about valid backup participants, parse any
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 9739e38..9847edf 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -28,11 +28,15 @@
 import android.content.Intent;
 import android.os.Binder;
 import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
@@ -75,6 +79,8 @@
     final boolean mGlobalDisable;
     volatile BackupManagerServiceInterface mService;
 
+    private HandlerThread mHandlerThread;
+
     public Trampoline(Context context) {
         mContext = context;
         mGlobalDisable = isBackupDisabled();
@@ -111,11 +117,11 @@
     }
 
     protected BackupManagerServiceInterface createRefactoredBackupManagerService() {
-        return new RefactoredBackupManagerService(mContext, this);
+        return new RefactoredBackupManagerService(mContext, this, mHandlerThread);
     }
 
     protected BackupManagerServiceInterface createBackupManagerService() {
-        return new BackupManagerService(mContext, this);
+        return new BackupManagerService(mContext, this, mHandlerThread);
     }
 
     // internal control API
@@ -140,10 +146,21 @@
     }
 
     void unlockSystemUser() {
-        BackupManagerServiceInterface svc = mService;
-        if (svc != null) {
-            svc.unlockSystemUser();
-        }
+        mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND);
+        mHandlerThread.start();
+
+        Handler h = new Handler(mHandlerThread.getLooper());
+        h.post(() -> {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup init");
+            initialize(UserHandle.USER_SYSTEM);
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
+            BackupManagerServiceInterface svc = mService;
+            Slog.i(TAG, "Unlocking system user; mService=" + mService);
+            if (svc != null) {
+                svc.unlockSystemUser();
+            }
+        });
     }
 
     public void setBackupServiceActive(final int userHandle, boolean makeActive) {
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 599485f..1659133 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -34,6 +34,8 @@
     time_zone_distro \
     time_zone_distro_installer \
     android.hidl.base-V1.0-java \
+    android.hardware.health-V1.0-java \
+    android.hardware.health-V2.0-java \
     android.hardware.weaver-V1.0-java \
     android.hardware.biometrics.fingerprint-V2.1-java \
     android.hardware.oemlock-V1.0-java \
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 50b8df2..4ffa5f1 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -491,7 +491,8 @@
             return Collections.emptyList();
         }
         synchronized (this) {
-            Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false);
+            Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* edit */,
+                    false /* uidMismatchExpected */);
             if (pkgOps == null) {
                 return null;
             }
@@ -530,7 +531,8 @@
 
     private void pruneOp(Op op, int uid, String packageName) {
         if (op.time == 0 && op.rejectTime == 0) {
-            Ops ops = getOpsRawLocked(uid, packageName, false);
+            Ops ops = getOpsRawLocked(uid, packageName, false /* edit */,
+                    false /* uidMismatchExpected */);
             if (ops != null) {
                 ops.remove(op.op);
                 if (ops.size() <= 0) {
@@ -1046,7 +1048,9 @@
     public int checkPackage(int uid, String packageName) {
         Preconditions.checkNotNull(packageName);
         synchronized (this) {
-            if (getOpsRawLocked(uid, packageName, true) != null) {
+            Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
+                    true /* uidMismatchExpected */);
+            if (ops != null) {
                 return AppOpsManager.MODE_ALLOWED;
             } else {
                 return AppOpsManager.MODE_ERRORED;
@@ -1090,7 +1094,8 @@
     private int noteOperationUnchecked(int code, int uid, String packageName,
             int proxyUid, String proxyPackageName) {
         synchronized (this) {
-            Ops ops = getOpsRawLocked(uid, packageName, true);
+            Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
+                    false /* uidMismatchExpected */);
             if (ops == null) {
                 if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
                         + " package " + packageName);
@@ -1148,7 +1153,8 @@
         }
         ClientState client = (ClientState)token;
         synchronized (this) {
-            Ops ops = getOpsRawLocked(uid, resolvedPackageName, true);
+            Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */,
+                    false /* uidMismatchExpected */);
             if (ops == null) {
                 if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid
                         + " package " + resolvedPackageName);
@@ -1274,7 +1280,8 @@
         return uidState;
     }
 
-    private Ops getOpsRawLocked(int uid, String packageName, boolean edit) {
+    private Ops getOpsRawLocked(int uid, String packageName, boolean edit,
+            boolean uidMismatchExpected) {
         UidState uidState = getUidStateLocked(uid, edit);
         if (uidState == null) {
             return null;
@@ -1326,10 +1333,12 @@
                     if (pkgUid != uid) {
                         // Oops!  The package name is not valid for the uid they are calling
                         // under.  Abort.
-                        RuntimeException ex = new RuntimeException("here");
-                        ex.fillInStackTrace();
-                        Slog.w(TAG, "Bad call: specified package " + packageName
-                                + " under uid " + uid + " but it is really " + pkgUid, ex);
+                        if (!uidMismatchExpected) {
+                            RuntimeException ex = new RuntimeException("here");
+                            ex.fillInStackTrace();
+                            Slog.w(TAG, "Bad call: specified package " + packageName
+                                    + " under uid " + uid + " but it is really " + pkgUid, ex);
+                        }
                         return null;
                     }
                 } finally {
@@ -1359,7 +1368,8 @@
     }
 
     private Op getOpLocked(int code, int uid, String packageName, boolean edit) {
-        Ops ops = getOpsRawLocked(uid, packageName, edit);
+        Ops ops = getOpsRawLocked(uid, packageName, edit,
+                false /* uidMismatchExpected */);
         if (ops == null) {
             return null;
         }
@@ -1393,7 +1403,8 @@
                 if (AppOpsManager.opAllowSystemBypassRestriction(code)) {
                     // If we are the system, bypass user restrictions for certain codes
                     synchronized (this) {
-                        Ops ops = getOpsRawLocked(uid, packageName, true);
+                        Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
+                                false /* uidMismatchExpected */);
                         if ((ops != null) && ops.isPrivileged) {
                             return false;
                         }
@@ -1713,7 +1724,8 @@
                         out.startTag(null, "uid");
                         out.attribute(null, "n", Integer.toString(pkg.getUid()));
                         synchronized (this) {
-                            Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(), false);
+                            Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(),
+                                    false /* edit */, false /* uidMismatchExpected */);
                             // Should always be present as the list of PackageOps is generated
                             // from Ops.
                             if (ops != null) {
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 5106c8d..6d9c977 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -35,6 +35,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.hardware.health.V2_0.HealthInfo;
 import android.os.BatteryManager;
 import android.os.BatteryManagerInternal;
 import android.os.BatteryProperties;
@@ -118,8 +119,8 @@
 
     private final Object mLock = new Object();
 
-    private BatteryProperties mBatteryProps;
-    private final BatteryProperties mLastBatteryProps = new BatteryProperties();
+    private HealthInfo mHealthInfo;
+    private final HealthInfo mLastHealthInfo = new HealthInfo();
     private boolean mBatteryLevelCritical;
     private int mLastBatteryStatus;
     private int mLastBatteryHealth;
@@ -251,16 +252,16 @@
     private boolean isPoweredLocked(int plugTypeSet) {
         // assume we are powered if battery state is unknown so
         // the "stay on while plugged in" option will work.
-        if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
+        if (mHealthInfo.legacy.batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
             return true;
         }
-        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mBatteryProps.chargerAcOnline) {
+        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mHealthInfo.legacy.chargerAcOnline) {
             return true;
         }
-        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0 && mBatteryProps.chargerUsbOnline) {
+        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0 && mHealthInfo.legacy.chargerUsbOnline) {
             return true;
         }
-        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mBatteryProps.chargerWirelessOnline) {
+        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mHealthInfo.legacy.chargerWirelessOnline) {
             return true;
         }
         return false;
@@ -277,15 +278,15 @@
          *   (becomes <= mLowBatteryWarningLevel).
          */
         return !plugged
-                && mBatteryProps.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
-                && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel
+                && mHealthInfo.legacy.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
+                && mHealthInfo.legacy.batteryLevel <= mLowBatteryWarningLevel
                 && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);
     }
 
     private void shutdownIfNoPowerLocked() {
         // shut down gracefully if our battery is critically low and we are not powered.
         // wait until the system has booted before attempting to display the shutdown dialog.
-        if (mBatteryProps.batteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)) {
+        if (mHealthInfo.legacy.batteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -306,7 +307,7 @@
         // shut down gracefully if temperature is too high (> 68.0C by default)
         // wait until the system has booted before attempting to display the
         // shutdown dialog.
-        if (mBatteryProps.batteryTemperature > mShutdownBatteryTemperature) {
+        if (mHealthInfo.legacy.batteryTemperature > mShutdownBatteryTemperature) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -326,25 +327,66 @@
     private void update(BatteryProperties props) {
         synchronized (mLock) {
             if (!mUpdatesStopped) {
-                mBatteryProps = props;
+                mHealthInfo = new HealthInfo();
+                copy(mHealthInfo, props);
                 // Process the new values.
                 processValuesLocked(false);
             } else {
-                mLastBatteryProps.set(props);
+                copy(mLastHealthInfo, props);
             }
         }
     }
 
+    private static void copy(HealthInfo dst, HealthInfo src) {
+        dst.legacy.chargerAcOnline = src.legacy.chargerAcOnline;
+        dst.legacy.chargerUsbOnline = src.legacy.chargerUsbOnline;
+        dst.legacy.chargerWirelessOnline = src.legacy.chargerWirelessOnline;
+        dst.legacy.maxChargingCurrent = src.legacy.maxChargingCurrent;
+        dst.legacy.maxChargingVoltage = src.legacy.maxChargingVoltage;
+        dst.legacy.batteryStatus = src.legacy.batteryStatus;
+        dst.legacy.batteryHealth = src.legacy.batteryHealth;
+        dst.legacy.batteryPresent = src.legacy.batteryPresent;
+        dst.legacy.batteryLevel = src.legacy.batteryLevel;
+        dst.legacy.batteryVoltage = src.legacy.batteryVoltage;
+        dst.legacy.batteryTemperature = src.legacy.batteryTemperature;
+        dst.legacy.batteryCurrent = src.legacy.batteryCurrent;
+        dst.legacy.batteryCycleCount = src.legacy.batteryCycleCount;
+        dst.legacy.batteryFullCharge = src.legacy.batteryFullCharge;
+        dst.legacy.batteryChargeCounter = src.legacy.batteryChargeCounter;
+        dst.legacy.batteryTechnology = src.legacy.batteryTechnology;
+        dst.batteryCurrentAverage = src.batteryCurrentAverage;
+        dst.batteryCapacity = src.batteryCapacity;
+        dst.energyCounter = src.energyCounter;
+    }
+
+    // TODO(b/62229583): remove this function when BatteryProperties are completely replaced.
+    private static void copy(HealthInfo dst, BatteryProperties src) {
+        dst.legacy.chargerAcOnline = src.chargerAcOnline;
+        dst.legacy.chargerUsbOnline = src.chargerUsbOnline;
+        dst.legacy.chargerWirelessOnline = src.chargerWirelessOnline;
+        dst.legacy.maxChargingCurrent = src.maxChargingCurrent;
+        dst.legacy.maxChargingVoltage = src.maxChargingVoltage;
+        dst.legacy.batteryStatus = src.batteryStatus;
+        dst.legacy.batteryHealth = src.batteryHealth;
+        dst.legacy.batteryPresent = src.batteryPresent;
+        dst.legacy.batteryLevel = src.batteryLevel;
+        dst.legacy.batteryVoltage = src.batteryVoltage;
+        dst.legacy.batteryTemperature = src.batteryTemperature;
+        dst.legacy.batteryFullCharge = src.batteryFullCharge;
+        dst.legacy.batteryChargeCounter = src.batteryChargeCounter;
+        dst.legacy.batteryTechnology = src.batteryTechnology;
+    }
+
     private void processValuesLocked(boolean force) {
         boolean logOutlier = false;
         long dischargeDuration = 0;
 
-        mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
-        if (mBatteryProps.chargerAcOnline) {
+        mBatteryLevelCritical = (mHealthInfo.legacy.batteryLevel <= mCriticalBatteryLevel);
+        if (mHealthInfo.legacy.chargerAcOnline) {
             mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
-        } else if (mBatteryProps.chargerUsbOnline) {
+        } else if (mHealthInfo.legacy.chargerUsbOnline) {
             mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
-        } else if (mBatteryProps.chargerWirelessOnline) {
+        } else if (mHealthInfo.legacy.chargerWirelessOnline) {
             mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
         } else {
             mPlugType = BATTERY_PLUGGED_NONE;
@@ -352,30 +394,17 @@
 
         if (DEBUG) {
             Slog.d(TAG, "Processing new values: "
-                    + "chargerAcOnline=" + mBatteryProps.chargerAcOnline
-                    + ", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline
-                    + ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
-                    + ", maxChargingCurrent" + mBatteryProps.maxChargingCurrent
-                    + ", maxChargingVoltage" + mBatteryProps.maxChargingVoltage
-                    + ", batteryStatus=" + mBatteryProps.batteryStatus
-                    + ", batteryHealth=" + mBatteryProps.batteryHealth
-                    + ", batteryPresent=" + mBatteryProps.batteryPresent
-                    + ", batteryLevel=" + mBatteryProps.batteryLevel
-                    + ", batteryTechnology=" + mBatteryProps.batteryTechnology
-                    + ", batteryVoltage=" + mBatteryProps.batteryVoltage
-                    + ", batteryChargeCounter=" + mBatteryProps.batteryChargeCounter
-                    + ", batteryFullCharge=" + mBatteryProps.batteryFullCharge
-                    + ", batteryTemperature=" + mBatteryProps.batteryTemperature
+                    + "info=" + mHealthInfo
                     + ", mBatteryLevelCritical=" + mBatteryLevelCritical
                     + ", mPlugType=" + mPlugType);
         }
 
         // Let the battery stats keep track of the current level.
         try {
-            mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
-                    mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
-                    mBatteryProps.batteryVoltage, mBatteryProps.batteryChargeCounter,
-                    mBatteryProps.batteryFullCharge);
+            mBatteryStats.setBatteryState(mHealthInfo.legacy.batteryStatus, mHealthInfo.legacy.batteryHealth,
+                    mPlugType, mHealthInfo.legacy.batteryLevel, mHealthInfo.legacy.batteryTemperature,
+                    mHealthInfo.legacy.batteryVoltage, mHealthInfo.legacy.batteryChargeCounter,
+                    mHealthInfo.legacy.batteryFullCharge);
         } catch (RemoteException e) {
             // Should never happen.
         }
@@ -383,16 +412,16 @@
         shutdownIfNoPowerLocked();
         shutdownIfOverTempLocked();
 
-        if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
-                mBatteryProps.batteryHealth != mLastBatteryHealth ||
-                mBatteryProps.batteryPresent != mLastBatteryPresent ||
-                mBatteryProps.batteryLevel != mLastBatteryLevel ||
+        if (force || (mHealthInfo.legacy.batteryStatus != mLastBatteryStatus ||
+                mHealthInfo.legacy.batteryHealth != mLastBatteryHealth ||
+                mHealthInfo.legacy.batteryPresent != mLastBatteryPresent ||
+                mHealthInfo.legacy.batteryLevel != mLastBatteryLevel ||
                 mPlugType != mLastPlugType ||
-                mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
-                mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
-                mBatteryProps.maxChargingCurrent != mLastMaxChargingCurrent ||
-                mBatteryProps.maxChargingVoltage != mLastMaxChargingVoltage ||
-                mBatteryProps.batteryChargeCounter != mLastChargeCounter ||
+                mHealthInfo.legacy.batteryVoltage != mLastBatteryVoltage ||
+                mHealthInfo.legacy.batteryTemperature != mLastBatteryTemperature ||
+                mHealthInfo.legacy.maxChargingCurrent != mLastMaxChargingCurrent ||
+                mHealthInfo.legacy.maxChargingVoltage != mLastMaxChargingVoltage ||
+                mHealthInfo.legacy.batteryChargeCounter != mLastChargeCounter ||
                 mInvalidCharger != mLastInvalidCharger)) {
 
             if (mPlugType != mLastPlugType) {
@@ -401,33 +430,33 @@
 
                     // There's no value in this data unless we've discharged at least once and the
                     // battery level has changed; so don't log until it does.
-                    if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryProps.batteryLevel) {
+                    if (mDischargeStartTime != 0 && mDischargeStartLevel != mHealthInfo.legacy.batteryLevel) {
                         dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
                         logOutlier = true;
                         EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration,
-                                mDischargeStartLevel, mBatteryProps.batteryLevel);
+                                mDischargeStartLevel, mHealthInfo.legacy.batteryLevel);
                         // make sure we see a discharge event before logging again
                         mDischargeStartTime = 0;
                     }
                 } else if (mPlugType == BATTERY_PLUGGED_NONE) {
                     // charging -> discharging or we just powered up
                     mDischargeStartTime = SystemClock.elapsedRealtime();
-                    mDischargeStartLevel = mBatteryProps.batteryLevel;
+                    mDischargeStartLevel = mHealthInfo.legacy.batteryLevel;
                 }
             }
-            if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
-                    mBatteryProps.batteryHealth != mLastBatteryHealth ||
-                    mBatteryProps.batteryPresent != mLastBatteryPresent ||
+            if (mHealthInfo.legacy.batteryStatus != mLastBatteryStatus ||
+                    mHealthInfo.legacy.batteryHealth != mLastBatteryHealth ||
+                    mHealthInfo.legacy.batteryPresent != mLastBatteryPresent ||
                     mPlugType != mLastPlugType) {
                 EventLog.writeEvent(EventLogTags.BATTERY_STATUS,
-                        mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mBatteryProps.batteryPresent ? 1 : 0,
-                        mPlugType, mBatteryProps.batteryTechnology);
+                        mHealthInfo.legacy.batteryStatus, mHealthInfo.legacy.batteryHealth, mHealthInfo.legacy.batteryPresent ? 1 : 0,
+                        mPlugType, mHealthInfo.legacy.batteryTechnology);
             }
-            if (mBatteryProps.batteryLevel != mLastBatteryLevel) {
+            if (mHealthInfo.legacy.batteryLevel != mLastBatteryLevel) {
                 // Don't do this just from voltage or temperature changes, that is
                 // too noisy.
                 EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,
-                        mBatteryProps.batteryLevel, mBatteryProps.batteryVoltage, mBatteryProps.batteryTemperature);
+                        mHealthInfo.legacy.batteryLevel, mHealthInfo.legacy.batteryVoltage, mHealthInfo.legacy.batteryTemperature);
             }
             if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
                     mPlugType == BATTERY_PLUGGED_NONE) {
@@ -440,16 +469,16 @@
             if (!mBatteryLevelLow) {
                 // Should we now switch in to low battery mode?
                 if (mPlugType == BATTERY_PLUGGED_NONE
-                        && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
+                        && mHealthInfo.legacy.batteryLevel <= mLowBatteryWarningLevel) {
                     mBatteryLevelLow = true;
                 }
             } else {
                 // Should we now switch out of low battery mode?
                 if (mPlugType != BATTERY_PLUGGED_NONE) {
                     mBatteryLevelLow = false;
-                } else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel)  {
+                } else if (mHealthInfo.legacy.batteryLevel >= mLowBatteryCloseWarningLevel)  {
                     mBatteryLevelLow = false;
-                } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
+                } else if (force && mHealthInfo.legacy.batteryLevel >= mLowBatteryWarningLevel) {
                     // If being forced, the previous state doesn't matter, we will just
                     // absolutely check to see if we are now above the warning level.
                     mBatteryLevelLow = false;
@@ -496,7 +525,7 @@
                     }
                 });
             } else if (mSentLowBatteryBroadcast &&
-                    mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) {
+                    mHealthInfo.legacy.batteryLevel >= mLowBatteryCloseWarningLevel) {
                 mSentLowBatteryBroadcast = false;
                 final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
                 statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -522,16 +551,16 @@
                 logOutlierLocked(dischargeDuration);
             }
 
-            mLastBatteryStatus = mBatteryProps.batteryStatus;
-            mLastBatteryHealth = mBatteryProps.batteryHealth;
-            mLastBatteryPresent = mBatteryProps.batteryPresent;
-            mLastBatteryLevel = mBatteryProps.batteryLevel;
+            mLastBatteryStatus = mHealthInfo.legacy.batteryStatus;
+            mLastBatteryHealth = mHealthInfo.legacy.batteryHealth;
+            mLastBatteryPresent = mHealthInfo.legacy.batteryPresent;
+            mLastBatteryLevel = mHealthInfo.legacy.batteryLevel;
             mLastPlugType = mPlugType;
-            mLastBatteryVoltage = mBatteryProps.batteryVoltage;
-            mLastBatteryTemperature = mBatteryProps.batteryTemperature;
-            mLastMaxChargingCurrent = mBatteryProps.maxChargingCurrent;
-            mLastMaxChargingVoltage = mBatteryProps.maxChargingVoltage;
-            mLastChargeCounter = mBatteryProps.batteryChargeCounter;
+            mLastBatteryVoltage = mHealthInfo.legacy.batteryVoltage;
+            mLastBatteryTemperature = mHealthInfo.legacy.batteryTemperature;
+            mLastMaxChargingCurrent = mHealthInfo.legacy.maxChargingCurrent;
+            mLastMaxChargingVoltage = mHealthInfo.legacy.maxChargingVoltage;
+            mLastChargeCounter = mHealthInfo.legacy.batteryChargeCounter;
             mLastBatteryLevelCritical = mBatteryLevelCritical;
             mLastInvalidCharger = mInvalidCharger;
         }
@@ -543,38 +572,26 @@
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
 
-        int icon = getIconLocked(mBatteryProps.batteryLevel);
+        int icon = getIconLocked(mHealthInfo.legacy.batteryLevel);
 
         intent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
-        intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryProps.batteryStatus);
-        intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth);
-        intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryProps.batteryPresent);
-        intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryProps.batteryLevel);
+        intent.putExtra(BatteryManager.EXTRA_STATUS, mHealthInfo.legacy.batteryStatus);
+        intent.putExtra(BatteryManager.EXTRA_HEALTH, mHealthInfo.legacy.batteryHealth);
+        intent.putExtra(BatteryManager.EXTRA_PRESENT, mHealthInfo.legacy.batteryPresent);
+        intent.putExtra(BatteryManager.EXTRA_LEVEL, mHealthInfo.legacy.batteryLevel);
         intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
         intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
         intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
-        intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryProps.batteryVoltage);
-        intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryProps.batteryTemperature);
-        intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryProps.batteryTechnology);
+        intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mHealthInfo.legacy.batteryVoltage);
+        intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mHealthInfo.legacy.batteryTemperature);
+        intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mHealthInfo.legacy.batteryTechnology);
         intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
-        intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
-        intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mBatteryProps.maxChargingVoltage);
-        intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mBatteryProps.batteryChargeCounter);
+        intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mHealthInfo.legacy.maxChargingCurrent);
+        intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mHealthInfo.legacy.maxChargingVoltage);
+        intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mHealthInfo.legacy.batteryChargeCounter);
         if (DEBUG) {
-            Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED.  level:" + mBatteryProps.batteryLevel +
-                    ", scale:" + BATTERY_SCALE + ", status:" + mBatteryProps.batteryStatus +
-                    ", health:" + mBatteryProps.batteryHealth +
-                    ", present:" + mBatteryProps.batteryPresent +
-                    ", voltage: " + mBatteryProps.batteryVoltage +
-                    ", temperature: " + mBatteryProps.batteryTemperature +
-                    ", technology: " + mBatteryProps.batteryTechnology +
-                    ", AC powered:" + mBatteryProps.chargerAcOnline +
-                    ", USB powered:" + mBatteryProps.chargerUsbOnline +
-                    ", Wireless powered:" + mBatteryProps.chargerWirelessOnline +
-                    ", icon:" + icon  + ", invalid charger:" + mInvalidCharger +
-                    ", maxChargingCurrent:" + mBatteryProps.maxChargingCurrent +
-                    ", maxChargingVoltage:" + mBatteryProps.maxChargingVoltage +
-                    ", chargeCounter:" + mBatteryProps.batteryChargeCounter);
+            Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. scale:" + BATTERY_SCALE
+                    + ", info:" + mHealthInfo.toString());
         }
 
         mHandler.post(new Runnable() {
@@ -635,14 +652,14 @@
                 long durationThreshold = Long.parseLong(durationThresholdString);
                 int dischargeThreshold = Integer.parseInt(dischargeThresholdString);
                 if (duration <= durationThreshold &&
-                        mDischargeStartLevel - mBatteryProps.batteryLevel >= dischargeThreshold) {
+                        mDischargeStartLevel - mHealthInfo.legacy.batteryLevel >= dischargeThreshold) {
                     // If the discharge cycle is bad enough we want to know about it.
                     logBatteryStatsLocked();
                 }
                 if (DEBUG) Slog.v(TAG, "duration threshold: " + durationThreshold +
                         " discharge threshold: " + dischargeThreshold);
                 if (DEBUG) Slog.v(TAG, "duration: " + duration + " discharge: " +
-                        (mDischargeStartLevel - mBatteryProps.batteryLevel));
+                        (mDischargeStartLevel - mHealthInfo.legacy.batteryLevel));
             } catch (NumberFormatException e) {
                 Slog.e(TAG, "Invalid DischargeThresholds GService string: " +
                         durationThresholdString + " or " + dischargeThresholdString);
@@ -651,14 +668,14 @@
     }
 
     private int getIconLocked(int level) {
-        if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
+        if (mHealthInfo.legacy.batteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
             return com.android.internal.R.drawable.stat_sys_battery_charge;
-        } else if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING) {
+        } else if (mHealthInfo.legacy.batteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING) {
             return com.android.internal.R.drawable.stat_sys_battery;
-        } else if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING
-                || mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_FULL) {
+        } else if (mHealthInfo.legacy.batteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING
+                || mHealthInfo.legacy.batteryStatus == BatteryManager.BATTERY_STATUS_FULL) {
             if (isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)
-                    && mBatteryProps.batteryLevel >= 100) {
+                    && mHealthInfo.legacy.batteryLevel >= 100) {
                 return com.android.internal.R.drawable.stat_sys_battery_charge;
             } else {
                 return com.android.internal.R.drawable.stat_sys_battery;
@@ -720,11 +737,11 @@
                 getContext().enforceCallingOrSelfPermission(
                         android.Manifest.permission.DEVICE_POWER, null);
                 if (!mUpdatesStopped) {
-                    mLastBatteryProps.set(mBatteryProps);
+                    copy(mLastHealthInfo, mHealthInfo);
                 }
-                mBatteryProps.chargerAcOnline = false;
-                mBatteryProps.chargerUsbOnline = false;
-                mBatteryProps.chargerWirelessOnline = false;
+                mHealthInfo.legacy.chargerAcOnline = false;
+                mHealthInfo.legacy.chargerUsbOnline = false;
+                mHealthInfo.legacy.chargerWirelessOnline = false;
                 long ident = Binder.clearCallingIdentity();
                 try {
                     mUpdatesStopped = true;
@@ -751,30 +768,30 @@
                 }
                 try {
                     if (!mUpdatesStopped) {
-                        mLastBatteryProps.set(mBatteryProps);
+                        copy(mLastHealthInfo, mHealthInfo);
                     }
                     boolean update = true;
                     switch (key) {
                         case "present":
-                            mBatteryProps.batteryPresent = Integer.parseInt(value) != 0;
+                            mHealthInfo.legacy.batteryPresent = Integer.parseInt(value) != 0;
                             break;
                         case "ac":
-                            mBatteryProps.chargerAcOnline = Integer.parseInt(value) != 0;
+                            mHealthInfo.legacy.chargerAcOnline = Integer.parseInt(value) != 0;
                             break;
                         case "usb":
-                            mBatteryProps.chargerUsbOnline = Integer.parseInt(value) != 0;
+                            mHealthInfo.legacy.chargerUsbOnline = Integer.parseInt(value) != 0;
                             break;
                         case "wireless":
-                            mBatteryProps.chargerWirelessOnline = Integer.parseInt(value) != 0;
+                            mHealthInfo.legacy.chargerWirelessOnline = Integer.parseInt(value) != 0;
                             break;
                         case "status":
-                            mBatteryProps.batteryStatus = Integer.parseInt(value);
+                            mHealthInfo.legacy.batteryStatus = Integer.parseInt(value);
                             break;
                         case "level":
-                            mBatteryProps.batteryLevel = Integer.parseInt(value);
+                            mHealthInfo.legacy.batteryLevel = Integer.parseInt(value);
                             break;
                         case "temp":
-                            mBatteryProps.batteryTemperature = Integer.parseInt(value);
+                            mHealthInfo.legacy.batteryTemperature = Integer.parseInt(value);
                             break;
                         case "invalid":
                             mInvalidCharger = Integer.parseInt(value);
@@ -806,7 +823,7 @@
                 try {
                     if (mUpdatesStopped) {
                         mUpdatesStopped = false;
-                        mBatteryProps.set(mLastBatteryProps);
+                        copy(mHealthInfo, mLastHealthInfo);
                         processValuesFromShellLocked(pw, opts);
                     }
                 } finally {
@@ -833,20 +850,20 @@
                 if (mUpdatesStopped) {
                     pw.println("  (UPDATES STOPPED -- use 'reset' to restart)");
                 }
-                pw.println("  AC powered: " + mBatteryProps.chargerAcOnline);
-                pw.println("  USB powered: " + mBatteryProps.chargerUsbOnline);
-                pw.println("  Wireless powered: " + mBatteryProps.chargerWirelessOnline);
-                pw.println("  Max charging current: " + mBatteryProps.maxChargingCurrent);
-                pw.println("  Max charging voltage: " + mBatteryProps.maxChargingVoltage);
-                pw.println("  Charge counter: " + mBatteryProps.batteryChargeCounter);
-                pw.println("  status: " + mBatteryProps.batteryStatus);
-                pw.println("  health: " + mBatteryProps.batteryHealth);
-                pw.println("  present: " + mBatteryProps.batteryPresent);
-                pw.println("  level: " + mBatteryProps.batteryLevel);
+                pw.println("  AC powered: " + mHealthInfo.legacy.chargerAcOnline);
+                pw.println("  USB powered: " + mHealthInfo.legacy.chargerUsbOnline);
+                pw.println("  Wireless powered: " + mHealthInfo.legacy.chargerWirelessOnline);
+                pw.println("  Max charging current: " + mHealthInfo.legacy.maxChargingCurrent);
+                pw.println("  Max charging voltage: " + mHealthInfo.legacy.maxChargingVoltage);
+                pw.println("  Charge counter: " + mHealthInfo.legacy.batteryChargeCounter);
+                pw.println("  status: " + mHealthInfo.legacy.batteryStatus);
+                pw.println("  health: " + mHealthInfo.legacy.batteryHealth);
+                pw.println("  present: " + mHealthInfo.legacy.batteryPresent);
+                pw.println("  level: " + mHealthInfo.legacy.batteryLevel);
                 pw.println("  scale: " + BATTERY_SCALE);
-                pw.println("  voltage: " + mBatteryProps.batteryVoltage);
-                pw.println("  temperature: " + mBatteryProps.batteryTemperature);
-                pw.println("  technology: " + mBatteryProps.batteryTechnology);
+                pw.println("  voltage: " + mHealthInfo.legacy.batteryVoltage);
+                pw.println("  temperature: " + mHealthInfo.legacy.batteryTemperature);
+                pw.println("  technology: " + mHealthInfo.legacy.batteryTechnology);
             } else {
                 Shell shell = new Shell();
                 shell.exec(mBinderService, null, fd, null, args, null, new ResultReceiver(null));
@@ -860,25 +877,25 @@
         synchronized (mLock) {
             proto.write(BatteryServiceDumpProto.ARE_UPDATES_STOPPED, mUpdatesStopped);
             int batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_NONE;
-            if (mBatteryProps.chargerAcOnline) {
+            if (mHealthInfo.legacy.chargerAcOnline) {
                 batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_AC;
-            } else if (mBatteryProps.chargerUsbOnline) {
+            } else if (mHealthInfo.legacy.chargerUsbOnline) {
                 batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_USB;
-            } else if (mBatteryProps.chargerWirelessOnline) {
+            } else if (mHealthInfo.legacy.chargerWirelessOnline) {
                 batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_WIRELESS;
             }
             proto.write(BatteryServiceDumpProto.PLUGGED, batteryPluggedValue);
-            proto.write(BatteryServiceDumpProto.MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
-            proto.write(BatteryServiceDumpProto.MAX_CHARGING_VOLTAGE, mBatteryProps.maxChargingVoltage);
-            proto.write(BatteryServiceDumpProto.CHARGE_COUNTER, mBatteryProps.batteryChargeCounter);
-            proto.write(BatteryServiceDumpProto.STATUS, mBatteryProps.batteryStatus);
-            proto.write(BatteryServiceDumpProto.HEALTH, mBatteryProps.batteryHealth);
-            proto.write(BatteryServiceDumpProto.IS_PRESENT, mBatteryProps.batteryPresent);
-            proto.write(BatteryServiceDumpProto.LEVEL, mBatteryProps.batteryLevel);
+            proto.write(BatteryServiceDumpProto.MAX_CHARGING_CURRENT, mHealthInfo.legacy.maxChargingCurrent);
+            proto.write(BatteryServiceDumpProto.MAX_CHARGING_VOLTAGE, mHealthInfo.legacy.maxChargingVoltage);
+            proto.write(BatteryServiceDumpProto.CHARGE_COUNTER, mHealthInfo.legacy.batteryChargeCounter);
+            proto.write(BatteryServiceDumpProto.STATUS, mHealthInfo.legacy.batteryStatus);
+            proto.write(BatteryServiceDumpProto.HEALTH, mHealthInfo.legacy.batteryHealth);
+            proto.write(BatteryServiceDumpProto.IS_PRESENT, mHealthInfo.legacy.batteryPresent);
+            proto.write(BatteryServiceDumpProto.LEVEL, mHealthInfo.legacy.batteryLevel);
             proto.write(BatteryServiceDumpProto.SCALE, BATTERY_SCALE);
-            proto.write(BatteryServiceDumpProto.VOLTAGE, mBatteryProps.batteryVoltage);
-            proto.write(BatteryServiceDumpProto.TEMPERATURE, mBatteryProps.batteryTemperature);
-            proto.write(BatteryServiceDumpProto.TECHNOLOGY, mBatteryProps.batteryTechnology);
+            proto.write(BatteryServiceDumpProto.VOLTAGE, mHealthInfo.legacy.batteryVoltage);
+            proto.write(BatteryServiceDumpProto.TEMPERATURE, mHealthInfo.legacy.batteryTemperature);
+            proto.write(BatteryServiceDumpProto.TECHNOLOGY, mHealthInfo.legacy.batteryTechnology);
         }
         proto.flush();
     }
@@ -911,8 +928,8 @@
          * Synchronize on BatteryService.
          */
         public void updateLightsLocked() {
-            final int level = mBatteryProps.batteryLevel;
-            final int status = mBatteryProps.batteryStatus;
+            final int level = mHealthInfo.legacy.batteryLevel;
+            final int status = mHealthInfo.legacy.batteryStatus;
             if (level < mLowBatteryWarningLevel) {
                 if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
                     // Solid red when battery is charging
@@ -985,7 +1002,7 @@
         @Override
         public int getBatteryLevel() {
             synchronized (mLock) {
-                return mBatteryProps.batteryLevel;
+                return mHealthInfo.legacy.batteryLevel;
             }
         }
 
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index 40499c9..119c9df 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -38,6 +38,8 @@
 
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.util.proto.ProtoOutputStream;
+
 import com.android.internal.util.FastPrintWriter;
 
 /**
@@ -279,6 +281,31 @@
         return printedSomething;
     }
 
+    void writeProtoMap(ProtoOutputStream proto, long fieldId, ArrayMap<String, F[]> map) {
+        int N = map.size();
+        for (int mapi = 0; mapi < N; mapi++) {
+            long token = proto.start(fieldId);
+            proto.write(IntentResolverProto.ArrayMapEntry.KEY, map.keyAt(mapi));
+            for (F f : map.valueAt(mapi)) {
+                if (f != null) {
+                    proto.write(IntentResolverProto.ArrayMapEntry.VALUES, f.toString());
+                }
+            }
+            proto.end(token);
+        }
+    }
+
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+        long token = proto.start(fieldId);
+        writeProtoMap(proto, IntentResolverProto.FULL_MIME_TYPES, mTypeToFilter);
+        writeProtoMap(proto, IntentResolverProto.BASE_MIME_TYPES, mBaseTypeToFilter);
+        writeProtoMap(proto, IntentResolverProto.WILD_MIME_TYPES, mWildTypeToFilter);
+        writeProtoMap(proto, IntentResolverProto.SCHEMES, mSchemeToFilter);
+        writeProtoMap(proto, IntentResolverProto.NON_DATA_ACTIONS, mActionToFilter);
+        writeProtoMap(proto, IntentResolverProto.MIME_TYPED_ACTIONS, mTypedActionToFilter);
+        proto.end(token);
+    }
+
     public boolean dump(PrintWriter out, String title, String prefix, String packageName,
             boolean printFilter, boolean collapseDuplicates) {
         String innerPrefix = prefix + "  ";
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 046eb76..8b79b9d 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -373,12 +373,24 @@
             if (mCurrentVibration.hasLongerTimeout(newOneShot.getTiming())
                     && newOneShot.getAmplitude() == currentOneShot.getAmplitude()) {
                 if (DEBUG) {
-                    Slog.e(TAG, "Ignoring incoming vibration in favor of current vibration");
+                    Slog.d(TAG, "Ignoring incoming vibration in favor of current vibration");
                 }
                 return;
             }
         }
 
+        // If the current vibration is repeating and the incoming one is non-repeating, then ignore
+        // the non-repeating vibration. This is so that we don't cancel vibrations that are meant
+        // to grab the attention of the user, like ringtones and alarms, in favor of one-shot
+        // vibrations that are likely quite short.
+        if (!isRepeatingVibration(effect)
+                && mCurrentVibration != null && isRepeatingVibration(mCurrentVibration.mEffect)) {
+            if (DEBUG) {
+                Slog.d(TAG, "Ignoring incoming vibration in favor of alarm vibration");
+            }
+            return;
+        }
+
         Vibration vib = new Vibration(token, effect, usageHint, uid, opPkg);
 
         // Only link against waveforms since they potentially don't have a finish if
@@ -404,6 +416,16 @@
         }
     }
 
+    private static boolean isRepeatingVibration(VibrationEffect effect) {
+        if (effect instanceof VibrationEffect.Waveform) {
+            final VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect;
+            if (waveform.getRepeatIndex() >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void addToPreviousVibrationsLocked(Vibration vib) {
         if (mPreviousVibrations.size() > mPreviousVibrationsLimit) {
             mPreviousVibrations.removeFirst();
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 8bcbfbe..6ed0555 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -16,9 +16,7 @@
 
 package com.android.server.am;
 
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.getStackIdForWindowingMode;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
@@ -48,13 +46,14 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.wm.ConfigurationContainer;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 /**
  * Exactly one of these classes per Display in the system. Capable of holding zero or more
  * attached {@link ActivityStack}s.
  */
-class ActivityDisplay extends ConfigurationContainer {
+class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityDisplay" : TAG_AM;
     private static final String TAG_STACK = TAG + POSTFIX_STACK;
 
@@ -68,7 +67,7 @@
 
     /** All of the stacks on this display. Order matters, topmost stack is in front of all other
      * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
-    final ArrayList<ActivityStack> mStacks = new ArrayList<>();
+    private final ArrayList<ActivityStack> mStacks = new ArrayList<>();
 
     /** Array of all UIDs that are present on the display. */
     private IntArray mDisplayAccessUIDs = new IntArray();
@@ -80,6 +79,13 @@
 
     private boolean mSleeping;
 
+    // Cached reference to some special stacks we tend to get a lot so we don't need to loop
+    // through the list to find them.
+    private ActivityStack mHomeStack = null;
+    private ActivityStack mRecentsStack = null;
+    private ActivityStack mPinnedStack = null;
+    private ActivityStack mSplitScreenPrimaryStack = null;
+
     ActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
         mSupervisor = supervisor;
         mDisplayId = displayId;
@@ -98,6 +104,7 @@
         }
         if (DEBUG_STACK) Slog.v(TAG_STACK, "addChild: attaching " + stack
                 + " to displayId=" + mDisplayId + " position=" + position);
+        addStackReferenceIfNeeded(stack);
         positionChildAt(stack, position);
         mSupervisor.mService.updateSleepIfNeededLocked();
     }
@@ -106,6 +113,7 @@
         if (DEBUG_STACK) Slog.v(TAG_STACK, "removeChild: detaching " + stack
                 + " from displayId=" + mDisplayId);
         mStacks.remove(stack);
+        removeStackReferenceIfNeeded(stack);
         mSupervisor.mService.updateSleepIfNeededLocked();
     }
 
@@ -150,6 +158,16 @@
      * @see ConfigurationContainer#isCompatible(int, int)
      */
     <T extends ActivityStack> T getStack(int windowingMode, int activityType) {
+        if (activityType == ACTIVITY_TYPE_HOME) {
+            return (T) mHomeStack;
+        } else if (activityType == ACTIVITY_TYPE_RECENTS) {
+            return (T) mRecentsStack;
+        }
+        if (windowingMode == WINDOWING_MODE_PINNED) {
+            return (T) mPinnedStack;
+        } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+            return (T) mSplitScreenPrimaryStack;
+        }
         for (int i = mStacks.size() - 1; i >= 0; --i) {
             final ActivityStack stack = mStacks.get(i);
             // TODO: Should undefined windowing and activity type be compatible with standard type?
@@ -213,10 +231,14 @@
         if (windowingMode == WINDOWING_MODE_UNDEFINED) {
             // TODO: Should be okay to have stacks with with undefined windowing mode long term, but
             // have to set them to something for now due to logic that depending on them.
-            windowingMode = WINDOWING_MODE_FULLSCREEN;
+            windowingMode = getWindowingMode(); // Put in current display's windowing mode
+            if (windowingMode == WINDOWING_MODE_UNDEFINED) {
+                // Else fullscreen for now...
+                windowingMode = WINDOWING_MODE_FULLSCREEN;
+            }
         }
 
-        final boolean inSplitScreenMode = hasSplitScreenStack();
+        final boolean inSplitScreenMode = hasSplitScreenPrimaryStack();
         if (!inSplitScreenMode
                 && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) {
             // Switch to fullscreen windowing mode if we are not in split-screen mode and we are
@@ -228,24 +250,7 @@
             windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
         }
 
-        int stackId = INVALID_STACK_ID;
-        if (mDisplayId == DEFAULT_DISPLAY && (activityType == ACTIVITY_TYPE_STANDARD
-                || activityType == ACTIVITY_TYPE_UNDEFINED)) {
-            // TODO: Will be removed once we are no longer using static stack ids.
-            stackId = getStackIdForWindowingMode(windowingMode);
-            if (stackId == INVALID_STACK_ID) {
-                // Whatever...put in fullscreen stack for now.
-                stackId = FULLSCREEN_WORKSPACE_STACK_ID;
-            }
-            final T stack = getStack(stackId);
-            if (stack != null) {
-                return stack;
-            }
-        }
-
-        if (stackId == INVALID_STACK_ID) {
-            stackId = mSupervisor.getNextStackId();
-        }
+        final int stackId = mSupervisor.getNextStackId();
 
         final T stack = createStackUnchecked(windowingMode, activityType, stackId, onTop);
 
@@ -291,7 +296,7 @@
                 if (stack.getWindowingMode() != windowingMode) {
                     continue;
                 }
-                mSupervisor.removeStackLocked(stack.mStackId);
+                mSupervisor.removeStack(stack);
             }
         }
     }
@@ -306,12 +311,63 @@
             for (int i = mStacks.size() - 1; i >= 0; --i) {
                 final ActivityStack stack = mStacks.get(i);
                 if (stack.getActivityType() == activityType) {
-                    mSupervisor.removeStackLocked(stack.mStackId);
+                    mSupervisor.removeStack(stack);
                 }
             }
         }
     }
 
+    void onStackWindowingModeChanged(ActivityStack stack) {
+        removeStackReferenceIfNeeded(stack);
+        addStackReferenceIfNeeded(stack);
+    }
+
+    private void addStackReferenceIfNeeded(ActivityStack stack) {
+        final int activityType = stack.getActivityType();
+        final int windowingMode = stack.getWindowingMode();
+
+        if (activityType == ACTIVITY_TYPE_HOME) {
+            if (mHomeStack != null && mHomeStack != stack) {
+                throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
+                        + mHomeStack + " already exist on display=" + this + " stack=" + stack);
+            }
+            mHomeStack = stack;
+        } else if (activityType == ACTIVITY_TYPE_RECENTS) {
+            if (mRecentsStack != null && mRecentsStack != stack) {
+                throw new IllegalArgumentException("addStackReferenceIfNeeded: recents stack="
+                        + mRecentsStack + " already exist on display=" + this + " stack=" + stack);
+            }
+            mRecentsStack = stack;
+        }
+        if (windowingMode == WINDOWING_MODE_PINNED) {
+            if (mPinnedStack != null && mPinnedStack != stack) {
+                throw new IllegalArgumentException("addStackReferenceIfNeeded: pinned stack="
+                        + mPinnedStack + " already exist on display=" + this
+                        + " stack=" + stack);
+            }
+            mPinnedStack = stack;
+        } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+            if (mSplitScreenPrimaryStack != null && mSplitScreenPrimaryStack != stack) {
+                throw new IllegalArgumentException("addStackReferenceIfNeeded:"
+                        + " split-screen-primary" + " stack=" + mSplitScreenPrimaryStack
+                        + " already exist on display=" + this + " stack=" + stack);
+            }
+            mSplitScreenPrimaryStack = stack;
+        }
+    }
+
+    private void removeStackReferenceIfNeeded(ActivityStack stack) {
+        if (stack == mHomeStack) {
+            mHomeStack = null;
+        } else if (stack == mRecentsStack) {
+            mRecentsStack = null;
+        } else if (stack == mPinnedStack) {
+            mPinnedStack = null;
+        } else if (stack == mSplitScreenPrimaryStack) {
+            mSplitScreenPrimaryStack = null;
+        }
+    }
+
     /** Returns the top visible stack activity type that isn't in the exclude windowing mode. */
     int getTopVisibleStackActivityType(int excludeWindowingMode) {
         for (int i = mStacks.size() - 1; i >= 0; --i) {
@@ -326,20 +382,42 @@
         return ACTIVITY_TYPE_UNDEFINED;
     }
 
-    ActivityStack getSplitScreenStack() {
-        return getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
+    /**
+     * Get the topmost stack on the display. It may be different from focused stack, because
+     * focus may be on another display.
+     */
+    ActivityStack getTopStack() {
+        return mStacks.isEmpty() ? null : mStacks.get(mStacks.size() - 1);
     }
 
-    boolean hasSplitScreenStack() {
-        return getSplitScreenStack() != null;
+    boolean isTopStack(ActivityStack stack) {
+        return stack == getTopStack();
+    }
+
+    int getIndexOf(ActivityStack stack) {
+        return mStacks.indexOf(stack);
+    }
+
+    void onLockTaskPackagesUpdated() {
+        for (int i = mStacks.size() - 1; i >= 0; --i) {
+            mStacks.get(i).onLockTaskPackagesUpdated();
+        }
+    }
+
+    ActivityStack getSplitScreenPrimaryStack() {
+        return mSplitScreenPrimaryStack;
+    }
+
+    boolean hasSplitScreenPrimaryStack() {
+        return mSplitScreenPrimaryStack != null;
     }
 
     PinnedActivityStack getPinnedStack() {
-        return getStack(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+        return (PinnedActivityStack) mPinnedStack;
     }
 
     boolean hasPinnedStack() {
-        return getPinnedStack() != null;
+        return mPinnedStack != null;
     }
 
     @Override
@@ -353,7 +431,7 @@
     }
 
     @Override
-    protected ConfigurationContainer getChildAt(int index) {
+    protected ActivityStack getChildAt(int index) {
         return mStacks.get(index);
     }
 
@@ -401,6 +479,10 @@
         mSleeping = asleep;
     }
 
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "displayId=" + mDisplayId + " mStacks=" + mStacks);
+    }
+
     public void writeToProto(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         super.writeToProto(proto, CONFIGURATION_CONTAINER);
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index 3a9bf12..ceb2ad6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -59,7 +59,6 @@
     static final boolean DEBUG_FOCUS = false;
     static final boolean DEBUG_IDLE = DEBUG_ALL_ACTIVITIES || false;
     static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
-    static final boolean DEBUG_LOCKSCREEN = DEBUG_ALL || false;
     static final boolean DEBUG_LOCKTASK = DEBUG_ALL || false;
     static final boolean DEBUG_LRU = DEBUG_ALL || false;
     static final boolean DEBUG_MU = DEBUG_ALL || false;
@@ -74,10 +73,10 @@
     static final boolean DEBUG_PROVIDER = DEBUG_ALL || false;
     static final boolean DEBUG_PSS = DEBUG_ALL || false;
     static final boolean DEBUG_RECENTS = DEBUG_ALL || false;
+    static final boolean DEBUG_RECENTS_TRIM_TASKS = DEBUG_RECENTS || false;
     static final boolean DEBUG_RELEASE = DEBUG_ALL_ACTIVITIES || false;
     static final boolean DEBUG_RESULTS = DEBUG_ALL || false;
     static final boolean DEBUG_SAVED_STATE = DEBUG_ALL_ACTIVITIES || false;
-    static final boolean DEBUG_SCREENSHOTS = DEBUG_ALL_ACTIVITIES || false;
     static final boolean DEBUG_SERVICE = DEBUG_ALL || false;
     static final boolean DEBUG_FOREGROUND_SERVICE = DEBUG_ALL || false;
     static final boolean DEBUG_SERVICE_EXECUTING = DEBUG_ALL || false;
@@ -85,7 +84,6 @@
     static final boolean DEBUG_STATES = DEBUG_ALL_ACTIVITIES || false;
     static final boolean DEBUG_SWITCH = DEBUG_ALL || false;
     static final boolean DEBUG_TASKS = DEBUG_ALL || false;
-    static final boolean DEBUG_THUMBNAILS = DEBUG_ALL || false;
     static final boolean DEBUG_TRANSITION = DEBUG_ALL || false;
     static final boolean DEBUG_UID_OBSERVERS = DEBUG_ALL || false;
     static final boolean DEBUG_URI_PERMISSION = DEBUG_ALL || false;
@@ -105,7 +103,6 @@
     static final String POSTFIX_FOCUS = (APPEND_CATEGORY_NAME) ? "_Focus" : "";
     static final String POSTFIX_IDLE = (APPEND_CATEGORY_NAME) ? "_Idle" : "";
     static final String POSTFIX_IMMERSIVE = (APPEND_CATEGORY_NAME) ? "_Immersive" : "";
-    static final String POSTFIX_LOCKSCREEN = (APPEND_CATEGORY_NAME) ? "_LockScreen" : "";
     static final String POSTFIX_LOCKTASK = (APPEND_CATEGORY_NAME) ? "_LockTask" : "";
     static final String POSTFIX_LRU = (APPEND_CATEGORY_NAME) ? "_LRU" : "";
     static final String POSTFIX_MU = "_MU";
@@ -122,7 +119,6 @@
     static final String POSTFIX_RELEASE = (APPEND_CATEGORY_NAME) ? "_Release" : "";
     static final String POSTFIX_RESULTS = (APPEND_CATEGORY_NAME) ? "_Results" : "";
     static final String POSTFIX_SAVED_STATE = (APPEND_CATEGORY_NAME) ? "_SavedState" : "";
-    static final String POSTFIX_SCREENSHOTS = (APPEND_CATEGORY_NAME) ? "_Screenshots" : "";
     static final String POSTFIX_SERVICE = (APPEND_CATEGORY_NAME) ? "_Service" : "";
     static final String POSTFIX_SERVICE_EXECUTING =
             (APPEND_CATEGORY_NAME) ? "_ServiceExecuting" : "";
@@ -130,13 +126,11 @@
     static final String POSTFIX_STATES = (APPEND_CATEGORY_NAME) ? "_States" : "";
     static final String POSTFIX_SWITCH = (APPEND_CATEGORY_NAME) ? "_Switch" : "";
     static final String POSTFIX_TASKS = (APPEND_CATEGORY_NAME) ? "_Tasks" : "";
-    static final String POSTFIX_THUMBNAILS = (APPEND_CATEGORY_NAME) ? "_Thumbnails" : "";
     static final String POSTFIX_TRANSITION = (APPEND_CATEGORY_NAME) ? "_Transition" : "";
     static final String POSTFIX_UID_OBSERVERS = (APPEND_CATEGORY_NAME)
             ? "_UidObservers" : "";
     static final String POSTFIX_URI_PERMISSION = (APPEND_CATEGORY_NAME) ? "_UriPermission" : "";
     static final String POSTFIX_USER_LEAVING = (APPEND_CATEGORY_NAME) ? "_UserLeaving" : "";
     static final String POSTFIX_VISIBILITY = (APPEND_CATEGORY_NAME) ? "_Visibility" : "";
-    static final String POSTFIX_VISIBLE_BEHIND = (APPEND_CATEGORY_NAME) ? "_VisibleBehind" : "";
 
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e6fe620..5f377f7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -27,18 +27,10 @@
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.app.ActivityManager.StackId.getWindowingModeForStackId;
-import static android.app.ActivityManager.StackId.isStaticStack;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
@@ -57,6 +49,9 @@
 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
 import static android.os.Build.VERSION_CODES.N;
+import static android.os.IServiceManager.DUMP_PRIORITY_CRITICAL;
+import static android.os.IServiceManager.DUMP_PRIORITY_HIGH;
+import static android.os.IServiceManager.DUMP_PRIORITY_NORMAL;
 import static android.os.Process.BLUETOOTH_UID;
 import static android.os.Process.FIRST_APPLICATION_UID;
 import static android.os.Process.FIRST_ISOLATED_UID;
@@ -137,7 +132,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
@@ -182,7 +176,6 @@
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
-import static com.android.server.am.proto.ActivityManagerServiceProto.ACTIVITIES;
 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
@@ -199,7 +192,6 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityManager.StackId;
 import android.app.ActivityManager.StackInfo;
 import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityManagerInternal;
@@ -216,7 +208,6 @@
 import android.app.Dialog;
 import android.app.IActivityController;
 import android.app.IActivityManager;
-import android.app.IAppTask;
 import android.app.IApplicationThread;
 import android.app.IInstrumentationWatcher;
 import android.app.INotificationManager;
@@ -404,6 +395,9 @@
 import com.android.server.ThreadPriorityBooster;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.am.proto.ActivityManagerServiceProto;
+import com.android.server.am.proto.BroadcastProto;
+import com.android.server.am.proto.StickyBroadcastProto;
 import com.android.server.firewall.IntentFirewall;
 import com.android.server.job.JobSchedulerInternal;
 import com.android.server.pm.Installer;
@@ -739,9 +733,6 @@
                 doDump(fd, pw, new String[] {"associations"});
             }
             doDump(fd, pw, new String[] {"processes"});
-            doDump(fd, pw, new String[] {"-v", "all"});
-            doDump(fd, pw, new String[] {"service", "all"});
-            doDump(fd, pw, new String[] {"provider", "all"});
         }
 
         @Override
@@ -753,6 +744,8 @@
     public boolean canShowErrorDialogs() {
         return mShowDialogs && !mSleeping && !mShuttingDown
                 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
+                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
+                        mUserController.getCurrentUserId())
                 && !(UserManager.isDeviceInDemoMode(mContext)
                         && mUserController.getCurrentUser().isDemo());
     }
@@ -1738,9 +1731,6 @@
      */
     private boolean mUserIsMonkey;
 
-    /** Flag whether the device has a Recents UI */
-    boolean mHasRecents;
-
     /** The dimensions of the thumbnails in the Recents UI. */
     int mThumbnailWidth;
     int mThumbnailHeight;
@@ -2111,7 +2101,8 @@
                     String text = mContext.getString(R.string.heavy_weight_notification,
                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
                     Notification notification =
-                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
+                            new Notification.Builder(context,
+                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                             .setWhen(0)
                             .setOngoing(true)
@@ -2145,7 +2136,7 @@
                 }
                 try {
                     inm.cancelNotificationWithTag("android", null,
-                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
+                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
                 } catch (RuntimeException e) {
                     Slog.w(ActivityManagerService.TAG,
                             "Error canceling notification for service", e);
@@ -2503,13 +2494,16 @@
 
     public void setSystemProcess() {
         try {
-            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
+            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
+                    DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_NORMAL);
             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
-            ServiceManager.addService("meminfo", new MemBinder(this));
+            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
+                    DUMP_PRIORITY_HIGH | DUMP_PRIORITY_NORMAL);
             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
             ServiceManager.addService("dbinfo", new DbBinder(this));
             if (MONITOR_CPU_USAGE) {
-                ServiceManager.addService("cpuinfo", new CpuBinder(this));
+                ServiceManager.addService("cpuinfo", new CpuBinder(this),
+                        /* allowIsolated= */ false, DUMP_PRIORITY_CRITICAL);
             }
             ServiceManager.addService("permission", new PermissionController(this));
             ServiceManager.addService("processinfo", new ProcessInfoService(this));
@@ -2540,7 +2534,6 @@
         synchronized (this) {
             mWindowManager = wm;
             mStackSupervisor.setWindowManager(wm);
-            mActivityStarter.setWindowManager(wm);
             mLockTaskController.setWindowManager(wm);
         }
     }
@@ -2782,8 +2775,9 @@
         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
         mTaskChangeNotificationController =
                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
-        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
+        mActivityStarter = new ActivityStarter(this);
         mRecentTasks = new RecentTasks(this, mStackSupervisor);
+        mStackSupervisor.setRecentTasks(mRecentTasks);
         mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
 
         mProcessCpuThread = new Thread("CpuTracker") {
@@ -3241,11 +3235,12 @@
         // stack implementation changes in the future, keep in mind that the use of the fullscreen
         // stack is a means to move the activity to the main display and a moveActivityToDisplay()
         // option would be a better choice here.
-        if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
+        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
             Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
                     + " to main stack for VR");
-            setTaskWindowingMode(r.getTask().taskId,
-                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */);
+            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
+                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
+            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
         }
         mHandler.sendMessage(
                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
@@ -5095,11 +5090,12 @@
         }
 
         synchronized(this) {
-            if (mHeavyWeightProcess == null) {
+            final ProcessRecord proc = mHeavyWeightProcess;
+            if (proc == null) {
                 return;
             }
 
-            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
+            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
             for (int i = 0; i < activities.size(); i++) {
                 ActivityRecord r = activities.get(i);
                 if (!r.finishing && r.isInStackLocked()) {
@@ -5109,7 +5105,7 @@
             }
 
             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
-                    mHeavyWeightProcess.userId, 0));
+                    proc.userId, 0));
             mHeavyWeightProcess = null;
         }
     }
@@ -5428,7 +5424,7 @@
             boolean doLowMem = app.instr == null;
             boolean doOomAdj = doLowMem;
             if (!app.killedByAm) {
-                maybeNotifyTopAppKilled(app);
+                maybeNotifyTopAppKilledLocked(app);
                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
                         + ProcessList.makeOomAdjString(app.setAdj)
                         + ProcessList.makeProcStateString(app.setProcState));
@@ -5463,8 +5459,8 @@
     }
 
     /** Show system error dialog when a top app is killed by LMK */
-    void maybeNotifyTopAppKilled(ProcessRecord app) {
-        if (!shouldNotifyTopAppKilled(app)) {
+    void maybeNotifyTopAppKilledLocked(ProcessRecord app) {
+        if (!shouldNotifyTopAppKilledLocked(app)) {
             return;
         }
 
@@ -5474,8 +5470,10 @@
     }
 
     /** Only show notification when the top app is killed on low ram devices */
-    private boolean shouldNotifyTopAppKilled(ProcessRecord app) {
-        return app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
+    private boolean shouldNotifyTopAppKilledLocked(ProcessRecord app) {
+        final ActivityRecord TOP_ACT = resumedAppLocked();
+        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
+        return app == TOP_APP &&
             ActivityManager.isLowRamDeviceStatic();
     }
 
@@ -5963,16 +5961,7 @@
 
                 if (appInfo != null) {
                     forceStopPackageLocked(packageName, appInfo.uid, "clear data");
-                    // Remove all tasks match the cleared application package and user
-                    for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
-                        final TaskRecord tr = mRecentTasks.get(i);
-                        final String taskPackageName =
-                                tr.getBaseIntent().getComponent().getPackageName();
-                        if (tr.userId != resolvedUserId) continue;
-                        if (!taskPackageName.equals(packageName)) continue;
-                        mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
-                                REMOVE_FROM_RECENTS);
-                    }
+                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
                 }
             }
 
@@ -6553,7 +6542,7 @@
         }
 
         // Clean-up disabled tasks
-        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
+        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
 
         // Clean-up disabled services.
         mServices.bringDownDisabledPackageServicesLocked(
@@ -8084,8 +8073,8 @@
     }
 
     private boolean isInPictureInPictureMode(ActivityRecord r) {
-        if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
-                r.getStack().isInStackLocked(r) == null) {
+        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
+                || r.getStack().isInStackLocked(r) == null) {
             return false;
         }
 
@@ -8179,7 +8168,7 @@
 
                 // Only update the saved args from the args that are set
                 r.pictureInPictureArgs.copyOnlySet(params);
-                if (r.getStack().getStackId() == PINNED_STACK_ID) {
+                if (r.inPinnedWindowingMode()) {
                     // If the activity is already in picture-in-picture, update the pinned stack now
                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
                     // be used the next time the activity enters PiP
@@ -9800,35 +9789,12 @@
     public List<IBinder> getAppTasks(String callingPackage) {
         int callingUid = Binder.getCallingUid();
         long ident = Binder.clearCallingIdentity();
-
-        synchronized(this) {
-            ArrayList<IBinder> list = new ArrayList<IBinder>();
-            try {
-                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
-
-                final int N = mRecentTasks.size();
-                for (int i = 0; i < N; i++) {
-                    TaskRecord tr = mRecentTasks.get(i);
-                    // Skip tasks that do not match the caller.  We don't need to verify
-                    // callingPackage, because we are also limiting to callingUid and know
-                    // that will limit to the correct security sandbox.
-                    if (tr.effectiveUid != callingUid) {
-                        continue;
-                    }
-                    Intent intent = tr.getBaseIntent();
-                    if (intent == null ||
-                            !callingPackage.equals(intent.getComponent().getPackageName())) {
-                        continue;
-                    }
-                    ActivityManager.RecentTaskInfo taskInfo =
-                            createRecentTaskInfoFromTaskRecord(tr);
-                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
-                    list.add(taskImpl.asBinder());
-                }
-            } finally {
-                Binder.restoreCallingIdentity(ident);
+        try {
+            synchronized(this) {
+                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
             }
-            return list;
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
@@ -9851,58 +9817,6 @@
         return list;
     }
 
-    /**
-     * Creates a new RecentTaskInfo from a TaskRecord.
-     */
-    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
-        // Update the task description to reflect any changes in the task stack
-        tr.updateTaskDescription();
-
-        // Compose the recent task info
-        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
-        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
-        rti.persistentId = tr.taskId;
-        rti.baseIntent = new Intent(tr.getBaseIntent());
-        rti.origActivity = tr.origActivity;
-        rti.realActivity = tr.realActivity;
-        rti.description = tr.lastDescription;
-        rti.stackId = tr.getStackId();
-        rti.userId = tr.userId;
-        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
-        rti.firstActiveTime = tr.firstActiveTime;
-        rti.lastActiveTime = tr.lastActiveTime;
-        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
-        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
-        rti.numActivities = 0;
-        if (tr.mBounds != null) {
-            rti.bounds = new Rect(tr.mBounds);
-        }
-        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreenWindowingMode();
-        rti.resizeMode = tr.mResizeMode;
-        rti.configuration.setTo(tr.getConfiguration());
-
-        ActivityRecord base = null;
-        ActivityRecord top = null;
-        ActivityRecord tmp;
-
-        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
-            tmp = tr.mActivities.get(i);
-            if (tmp.finishing) {
-                continue;
-            }
-            base = tmp;
-            if (top == null || (top.state == ActivityState.INITIALIZING)) {
-                top = base;
-            }
-            rti.numActivities++;
-        }
-
-        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
-        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
-
-        return rti;
-    }
-
     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
@@ -9936,118 +9850,15 @@
         final int callingUid = Binder.getCallingUid();
         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
+        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
+                callingUid);
+        final boolean detailed = checkCallingPermission(
+                android.Manifest.permission.GET_DETAILED_TASKS)
+                        == PackageManager.PERMISSION_GRANTED;
 
-        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
-        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
         synchronized (this) {
-            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
+            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
                     callingUid);
-            final boolean detailed = checkCallingPermission(
-                    android.Manifest.permission.GET_DETAILED_TASKS)
-                    == PackageManager.PERMISSION_GRANTED;
-
-            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
-                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
-                return ParceledListSlice.emptyList();
-            }
-            mRecentTasks.loadUserRecentsLocked(userId);
-
-            final int recentsCount = mRecentTasks.size();
-            ArrayList<ActivityManager.RecentTaskInfo> res =
-                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
-
-            final Set<Integer> includedUsers;
-            if (includeProfiles) {
-                includedUsers = mUserController.getProfileIds(userId);
-            } else {
-                includedUsers = new HashSet<>();
-            }
-            includedUsers.add(Integer.valueOf(userId));
-
-            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
-                TaskRecord tr = mRecentTasks.get(i);
-                // Only add calling user or related users recent tasks
-                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
-                    continue;
-                }
-
-                if (tr.realActivitySuspended) {
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
-                    continue;
-                }
-
-                // Return the entry if desired by the caller.  We always return
-                // the first entry, because callers always expect this to be the
-                // foreground app.  We may filter others if the caller has
-                // not supplied RECENT_WITH_EXCLUDED and there is some reason
-                // we should exclude the entry.
-
-                if (i == 0
-                        || withExcluded
-                        || (tr.intent == null)
-                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
-                                == 0)) {
-                    if (!allowed) {
-                        // If the caller doesn't have the GET_TASKS permission, then only
-                        // allow them to see a small subset of tasks -- their own and home.
-                        if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
-                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
-                            continue;
-                        }
-                    }
-                    final ActivityStack stack = tr.getStack();
-                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
-                        if (stack != null && stack.isHomeOrRecentsStack()) {
-                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                                    "Skipping, home or recents stack task: " + tr);
-                            continue;
-                        }
-                    }
-                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
-                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
-                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                                    "Skipping, top task in docked stack: " + tr);
-                            continue;
-                        }
-                    }
-                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
-                        if (stack != null && stack.isPinnedStack()) {
-                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                                    "Skipping, pinned stack task: " + tr);
-                            continue;
-                        }
-                    }
-                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
-                        // Don't include auto remove tasks that are finished or finishing.
-                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                                "Skipping, auto-remove without activity: " + tr);
-                        continue;
-                    }
-                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
-                            && !tr.isAvailable) {
-                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                                "Skipping, unavail real act: " + tr);
-                        continue;
-                    }
-
-                    if (!tr.mUserSetupComplete) {
-                        // Don't include task launched while user is not done setting-up.
-                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                                "Skipping, user setup not complete: " + tr);
-                        continue;
-                    }
-
-                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
-                    if (!detailed) {
-                        rti.baseIntent.replaceExtras((Bundle)null);
-                    }
-
-                    res.add(rti);
-                    maxNum--;
-                }
-            }
-            return new ParceledListSlice<>(res);
         }
     }
 
@@ -10119,23 +9930,10 @@
                 TaskRecord task = new TaskRecord(this,
                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
                         ainfo, intent, description);
-
-                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
-                if (trimIdx >= 0) {
-                    // If this would have caused a trim, then we'll abort because that
-                    // means it would be added at the end of the list but then just removed.
+                if (!mRecentTasks.addToBottom(task)) {
                     return INVALID_TASK_ID;
                 }
-
-                final int N = mRecentTasks.size();
-                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
-                    final TaskRecord tr = mRecentTasks.remove(N - 1);
-                    tr.removedFromRecents();
-                }
-
-                task.inRecents = true;
-                mRecentTasks.add(task);
-                r.getStack().addTask(task, false, "addAppTask");
+                r.getStack().addTask(task, !ON_TOP, "addAppTask");
 
                 // TODO: Send the thumbnail to WM to store it.
 
@@ -10351,38 +10149,6 @@
         mWindowManager.executeAppTransition();
     }
 
-    private void removeTasksByPackageNameLocked(String packageName, int userId) {
-        // Remove all tasks with activities in the specified package from the list of recent tasks
-        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
-            TaskRecord tr = mRecentTasks.get(i);
-            if (tr.userId != userId) continue;
-
-            ComponentName cn = tr.intent.getComponent();
-            if (cn != null && cn.getPackageName().equals(packageName)) {
-                // If the package name matches, remove the task.
-                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
-            }
-        }
-    }
-
-    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
-            int userId) {
-
-        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
-            TaskRecord tr = mRecentTasks.get(i);
-            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
-                continue;
-            }
-
-            ComponentName cn = tr.intent.getComponent();
-            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
-                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
-            if (sameComponent) {
-                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
-            }
-        }
-    }
-
     @Override
     public void removeStack(int stackId) {
         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
@@ -10390,11 +10156,14 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
-                if (stack != null && !stack.isActivityTypeStandardOrUndefined()) {
+                if (stack == null) {
+                    return;
+                }
+                if (!stack.isActivityTypeStandardOrUndefined()) {
                     throw new IllegalArgumentException(
                             "Removing non-standard stack is not allowed.");
                 }
-                mStackSupervisor.removeStackLocked(stackId);
+                mStackSupervisor.removeStack(stack);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -10609,7 +10378,7 @@
                 }
 
                 final ActivityStack stack = r.getStack();
-                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
+                if (stack == null || !stack.inFreeformWindowingMode()) {
                     throw new IllegalStateException(
                             "exitFreeformMode: You can only go fullscreen from freeform.");
                 }
@@ -10677,27 +10446,20 @@
 
                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
                         + " to stackId=" + stackId + " toTop=" + toTop);
-                if (stackId == DOCKED_STACK_ID) {
-                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
-                            null /* initialBounds */);
-                }
 
-                ActivityStack stack = mStackSupervisor.getStack(stackId);
+                final ActivityStack stack = mStackSupervisor.getStack(stackId);
                 if (stack == null) {
-                    if (!isStaticStack(stackId)) {
-                        throw new IllegalStateException(
-                                "moveTaskToStack: No stack for stackId=" + stackId);
-                    }
-                    final ActivityDisplay display = task.getStack().getDisplay();
-                    final int windowingMode =
-                            getWindowingModeForStackId(stackId, display.hasSplitScreenStack());
-                    stack = display.getOrCreateStack(windowingMode,
-                            task.getStack().getActivityType(), toTop);
+                    throw new IllegalStateException(
+                            "moveTaskToStack: No stack for stackId=" + stackId);
                 }
                 if (!stack.isActivityTypeStandardOrUndefined()) {
                     throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
                             + taskId + " to stack " + stackId);
                 }
+                if (stack.inSplitScreenPrimaryWindowingMode()) {
+                    mWindowManager.setDockedStackCreateState(
+                            DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
+                }
                 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
                         "moveTaskToStack");
             } finally {
@@ -10767,9 +10529,9 @@
         try {
             synchronized (this) {
                 final ActivityStack stack =
-                        mStackSupervisor.getDefaultDisplay().getSplitScreenStack();
+                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
                 if (toTop) {
-                    mStackSupervisor.resizeStackLocked(stack.mStackId, null /* destBounds */,
+                    mStackSupervisor.resizeStackLocked(stack, null /* destBounds */,
                             null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
                             true /* preserveWindows */, true /* allowResizeInDockedMode */,
                             !DEFER_RESUME);
@@ -10862,7 +10624,12 @@
                     stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
                             animationDuration, false /* fromFullscreen */);
                 } else {
-                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
+                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
+                    if (stack == null) {
+                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
+                        return;
+                    }
+                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
                             null /* tempTaskInsetBounds */, preserveWindows,
                             allowResizeInDockedMode, !DEFER_RESUME);
                 }
@@ -12938,6 +12705,10 @@
                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
                         + bugreportType);
         }
+        // Always log caller, even if it does not have permission to dump.
+        String type = extraOptions == null ? "bugreport" : extraOptions;
+        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
+
         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
         if (extraOptions != null) {
             SystemProperties.set("dumpstate.options", extraOptions);
@@ -14145,7 +13916,6 @@
 
             // Load resources only after the current configuration has been set.
             final Resources res = mContext.getResources();
-            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
             mThumbnailWidth = res.getDimensionPixelSize(
                     com.android.internal.R.dimen.thumbnail_width);
             mThumbnailHeight = res.getDimensionPixelSize(
@@ -15104,10 +14874,31 @@
         long origId = Binder.clearCallingIdentity();
 
         if (useProto) {
-            //TODO: Options when dumping proto
             final ProtoOutputStream proto = new ProtoOutputStream(fd);
-            synchronized (this) {
-                writeActivitiesToProtoLocked(proto);
+            String cmd = opti < args.length ? args[opti] : "";
+            opti++;
+
+            if ("activities".equals(cmd) || "a".equals(cmd)) {
+                // output proto is ActivityStackSupervisorProto
+                synchronized (this) {
+                    writeActivitiesToProtoLocked(proto);
+                }
+            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
+                // output proto is BroadcastProto
+                synchronized (this) {
+                    writeBroadcastsToProtoLocked(proto);
+                }
+            } else {
+                // default option, dump everything, output is ActivityManagerServiceProto
+                synchronized (this) {
+                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
+                    writeActivitiesToProtoLocked(proto);
+                    proto.end(activityToken);
+
+                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
+                    writeBroadcastsToProtoLocked(proto);
+                    proto.end(broadcastToken);
+                }
             }
             proto.flush();
             Binder.restoreCallingIdentity(origId);
@@ -15133,7 +14924,9 @@
                 }
             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
                 synchronized (this) {
-                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
+                    if (mRecentTasks != null) {
+                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
+                    }
                 }
             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
                 String[] newArgs;
@@ -15354,7 +15147,9 @@
                 if (dumpAll) {
                     pw.println("-------------------------------------------------------------------------------");
                 }
-                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
+                if (mRecentTasks != null) {
+                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
+                }
                 pw.println();
                 if (dumpAll) {
                     pw.println("-------------------------------------------------------------------------------");
@@ -15424,7 +15219,9 @@
                 if (dumpAll) {
                     pw.println("-------------------------------------------------------------------------------");
                 }
-                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
+                if (mRecentTasks != null) {
+                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
+                }
                 pw.println();
                 if (dumpAll) {
                     pw.println("-------------------------------------------------------------------------------");
@@ -15458,7 +15255,8 @@
     }
 
     private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
-        mStackSupervisor.writeToProto(proto, ACTIVITIES);
+        // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
+        mStackSupervisor.writeToProto(proto);
     }
 
     private void dumpLastANRLocked(PrintWriter pw) {
@@ -15510,42 +15308,6 @@
         }
     }
 
-    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll, String dumpPackage) {
-        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
-
-        boolean printedAnything = false;
-
-        if (mRecentTasks != null && mRecentTasks.size() > 0) {
-            boolean printedHeader = false;
-
-            final int N = mRecentTasks.size();
-            for (int i=0; i<N; i++) {
-                TaskRecord tr = mRecentTasks.get(i);
-                if (dumpPackage != null) {
-                    if (tr.realActivity == null ||
-                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
-                        continue;
-                    }
-                }
-                if (!printedHeader) {
-                    pw.println("  Recent tasks:");
-                    printedHeader = true;
-                    printedAnything = true;
-                }
-                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
-                        pw.println(tr);
-                if (dumpAll) {
-                    mRecentTasks.get(i).dump(pw, "    ");
-                }
-            }
-        }
-
-        if (!printedAnything) {
-            pw.println("  (nothing)");
-        }
-    }
-
     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
@@ -16372,6 +16134,40 @@
         }
     }
 
+    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
+        if (mRegisteredReceivers.size() > 0) {
+            Iterator it = mRegisteredReceivers.values().iterator();
+            while (it.hasNext()) {
+                ReceiverList r = (ReceiverList)it.next();
+                r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
+            }
+        }
+        mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
+        for (BroadcastQueue q : mBroadcastQueues) {
+            q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
+        }
+        for (int user=0; user<mStickyBroadcasts.size(); user++) {
+            long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
+            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
+            for (Map.Entry<String, ArrayList<Intent>> ent
+                    : mStickyBroadcasts.valueAt(user).entrySet()) {
+                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
+                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
+                for (Intent intent : ent.getValue()) {
+                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
+                            false, true, true, false);
+                }
+                proto.end(actionToken);
+            }
+            proto.end(token);
+        }
+
+        long handlerToken = proto.start(BroadcastProto.HANDLER);
+        proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
+        mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
+        proto.end(handlerToken);
+    }
+
     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage) {
         boolean needSep = false;
@@ -19360,7 +19156,7 @@
                                         // Remove all permissions granted from/to this package
                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
 
-                                        removeTasksByPackageNameLocked(ssp, userId);
+                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
 
                                         mServices.forceStopPackageLocked(ssp, userId);
 
@@ -20697,9 +20493,10 @@
     /** Helper method that requests bounds from WM and applies them to stack. */
     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
         final Rect newStackBounds = new Rect();
-        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
+        final ActivityStack stack = mStackSupervisor.getStack(stackId);
+        stack.getBoundsForNewConfiguration(newStackBounds);
         mStackSupervisor.resizeStackLocked(
-                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
+                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
     }
@@ -24367,125 +24164,6 @@
     }
 
     /**
-     * An implementation of IAppTask, that allows an app to manage its own tasks via
-     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
-     * only the process that calls getAppTasks() can call the AppTask methods.
-     */
-    class AppTaskImpl extends IAppTask.Stub {
-        private int mTaskId;
-        private int mCallingUid;
-
-        public AppTaskImpl(int taskId, int callingUid) {
-            mTaskId = taskId;
-            mCallingUid = callingUid;
-        }
-
-        private void checkCaller() {
-            if (mCallingUid != Binder.getCallingUid()) {
-                throw new SecurityException("Caller " + mCallingUid
-                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
-            }
-        }
-
-        @Override
-        public void finishAndRemoveTask() {
-            checkCaller();
-
-            synchronized (ActivityManagerService.this) {
-                long origId = Binder.clearCallingIdentity();
-                try {
-                    // We remove the task from recents to preserve backwards
-                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
-                            REMOVE_FROM_RECENTS)) {
-                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(origId);
-                }
-            }
-        }
-
-        @Override
-        public ActivityManager.RecentTaskInfo getTaskInfo() {
-            checkCaller();
-
-            synchronized (ActivityManagerService.this) {
-                long origId = Binder.clearCallingIdentity();
-                try {
-                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
-                    if (tr == null) {
-                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
-                    }
-                    return createRecentTaskInfoFromTaskRecord(tr);
-                } finally {
-                    Binder.restoreCallingIdentity(origId);
-                }
-            }
-        }
-
-        @Override
-        public void moveToFront() {
-            checkCaller();
-            // Will bring task to front if it already has a root activity.
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                synchronized (this) {
-                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
-                }
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-
-        @Override
-        public int startActivity(IBinder whoThread, String callingPackage,
-                Intent intent, String resolvedType, Bundle bOptions) {
-            checkCaller();
-
-            int callingUser = UserHandle.getCallingUserId();
-            TaskRecord tr;
-            IApplicationThread appThread;
-            synchronized (ActivityManagerService.this) {
-                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
-                if (tr == null) {
-                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
-                }
-                appThread = IApplicationThread.Stub.asInterface(whoThread);
-                if (appThread == null) {
-                    throw new IllegalArgumentException("Bad app thread " + appThread);
-                }
-            }
-            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
-                    resolvedType, null, null, null, null, 0, 0, null, null,
-                    null, bOptions, false, callingUser, tr, "AppTaskImpl");
-        }
-
-        @Override
-        public void setExcludeFromRecents(boolean exclude) {
-            checkCaller();
-
-            synchronized (ActivityManagerService.this) {
-                long origId = Binder.clearCallingIdentity();
-                try {
-                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
-                    if (tr == null) {
-                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
-                    }
-                    Intent intent = tr.getBaseIntent();
-                    if (exclude) {
-                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-                    } else {
-                        intent.setFlags(intent.getFlags()
-                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(origId);
-                }
-            }
-        }
-    }
-
-    /**
      * Kill processes for the user with id userId and that depend on the package named packageName
      */
     @Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 4c93423..f03d2d5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -73,10 +73,8 @@
 
 import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
 import static android.app.ActivityManager.RESIZE_MODE_USER;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.Display.INVALID_DISPLAY;
 
@@ -86,15 +84,6 @@
     public static final String NO_CLASS_ERROR_CODE = "Error type 3";
     private static final String SHELL_PACKAGE_NAME = "com.android.shell";
 
-    // Is the object moving in a positive direction?
-    private static final boolean MOVING_FORWARD = true;
-    // Is the object moving in the horizontal plan?
-    private static final boolean MOVING_HORIZONTALLY = true;
-    // Is the object current point great then its target point?
-    private static final boolean GREATER_THAN_TARGET = true;
-    // Amount we reduce the stack size by when testing a task re-size.
-    private static final int STACK_BOUNDS_INSET = 10;
-
     // IPC interface to activity manager -- don't need to do additional security checks.
     final IActivityManager mInterface;
 
@@ -1944,8 +1933,6 @@
                 return runStackInfo(pw);
             case "move-top-activity-to-pinned-stack":
                 return runMoveTopActivityToPinnedStack(pw);
-            case "size-docked-stack-test":
-                return runStackSizeDockedStackTest(pw);
             case "remove":
                 return runStackRemove(pw);
             default:
@@ -2143,89 +2130,6 @@
         return 0;
     }
 
-    int runStackSizeDockedStackTest(PrintWriter pw) throws RemoteException {
-        final PrintWriter err = getErrPrintWriter();
-        final int stepSize = Integer.parseInt(getNextArgRequired());
-        final String side = getNextArgRequired();
-        final String delayStr = getNextArg();
-        final int delayMs = (delayStr != null) ? Integer.parseInt(delayStr) : 0;
-
-        ActivityManager.StackInfo info = mInterface.getStackInfo(
-                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
-        if (info == null) {
-            err.println("Docked stack doesn't exist");
-            return -1;
-        }
-        if (info.bounds == null) {
-            err.println("Docked stack doesn't have a bounds");
-            return -1;
-        }
-        Rect bounds = info.bounds;
-
-        final boolean horizontalGrowth = "l".equals(side) || "r".equals(side);
-        final int changeSize = (horizontalGrowth ? bounds.width() : bounds.height()) / 2;
-        int currentPoint;
-        switch (side) {
-            case "l":
-                currentPoint = bounds.left;
-                break;
-            case "r":
-                currentPoint = bounds.right;
-                break;
-            case "t":
-                currentPoint = bounds.top;
-                break;
-            case "b":
-                currentPoint = bounds.bottom;
-                break;
-            default:
-                err.println("Unknown growth side: " + side);
-                return -1;
-        }
-
-        final int startPoint = currentPoint;
-        final int minPoint = currentPoint - changeSize;
-        final int maxPoint = currentPoint + changeSize;
-
-        int maxChange;
-        pw.println("Shrinking docked stack side=" + side);
-        pw.flush();
-        while (currentPoint > minPoint) {
-            maxChange = Math.min(stepSize, currentPoint - minPoint);
-            currentPoint -= maxChange;
-            setBoundsSide(bounds, side, currentPoint);
-            int res = resizeStack(DOCKED_STACK_ID, bounds, delayMs);
-            if (res < 0) {
-                return res;
-            }
-        }
-
-        pw.println("Growing docked stack side=" + side);
-        pw.flush();
-        while (currentPoint < maxPoint) {
-            maxChange = Math.min(stepSize, maxPoint - currentPoint);
-            currentPoint += maxChange;
-            setBoundsSide(bounds, side, currentPoint);
-            int res = resizeStack(DOCKED_STACK_ID, bounds, delayMs);
-            if (res < 0) {
-                return res;
-            }
-        }
-
-        pw.println("Back to Original size side=" + side);
-        pw.flush();
-        while (currentPoint > startPoint) {
-            maxChange = Math.min(stepSize, currentPoint - startPoint);
-            currentPoint -= maxChange;
-            setBoundsSide(bounds, side, currentPoint);
-            int res = resizeStack(DOCKED_STACK_ID, bounds, delayMs);
-            if (res < 0) {
-                return res;
-            }
-        }
-        return 0;
-    }
-
     void setBoundsSide(Rect bounds, String side, int value) {
         switch (side) {
             case "l":
@@ -2687,10 +2591,6 @@
             pw.println("           Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>");
             pw.println("           and supplying temporary different task bounds indicated by");
             pw.println("           <TASK_LEFT,TOP,RIGHT,BOTTOM>");
-            pw.println("       size-docked-stack-test: <STEP_SIZE> <l|t|r|b> [DELAY_MS]");
-            pw.println("           Test command for sizing docked stack by");
-            pw.println("           <STEP_SIZE> increments from the side <l>eft, <t>op, <r>ight, or <b>ottom");
-            pw.println("           applying the optional [DELAY_MS] between each step.");
             pw.println("       move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
             pw.println("           Moves the top activity from");
             pw.println("           <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the");
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index fdcb8c6..93c0f77 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -5,6 +5,7 @@
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
@@ -127,7 +128,7 @@
             case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
                 mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
                 break;
-            case WINDOW_STATE_FREEFORM:
+            case WINDOWING_MODE_FREEFORM:
                 mWindowState = WINDOW_STATE_FREEFORM;
                 break;
             default:
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 7b0b942..40e568c 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -17,9 +17,7 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX;
 import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
 import static android.app.ActivityOptions.ANIM_CUSTOM;
@@ -60,6 +58,10 @@
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
 import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
 import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
@@ -284,6 +286,7 @@
     int configChangeFlags;  // which config values have changed
     private boolean keysPaused;     // has key dispatching been paused for it?
     int launchMode;         // the launch mode activity attribute.
+    int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
     boolean visible;        // does this activity's window need to be shown?
     boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
                                      // might hide this activity?
@@ -661,8 +664,7 @@
             return;
         }
 
-        final boolean inPictureInPictureMode = (task.getStackId() == PINNED_STACK_ID) &&
-                (targetStackBounds != null);
+        final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
         if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
             // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
             // update that here in order
@@ -684,10 +686,6 @@
         }
     }
 
-    boolean isFreeform() {
-        return task != null && task.getStackId() == FREEFORM_WORKSPACE_STACK_ID;
-    }
-
     @Override
     protected int getChildCount() {
         // {@link ActivityRecord} is a leaf node and has no children.
@@ -831,23 +829,6 @@
         hasBeenLaunched = false;
         mStackSupervisor = supervisor;
 
-        mRotationAnimationHint = aInfo.rotationAnimation;
-
-        if (options != null) {
-            pendingOptions = options;
-            mLaunchTaskBehind = pendingOptions.getLaunchTaskBehind();
-
-            final int rotationAnimation = pendingOptions.getRotationAnimationHint();
-            // Only override manifest supplied option if set.
-            if (rotationAnimation >= 0) {
-                mRotationAnimationHint = rotationAnimation;
-            }
-            PendingIntent usageReport = pendingOptions.getUsageTimeReport();
-            if (usageReport != null) {
-                appTimeTracker = new AppTimeTracker(usageReport);
-            }
-        }
-
         // This starts out true, since the initial state of an activity is that we have everything,
         // and we shouldn't never consider it lacking in state to be removed if it dies.
         haveState = true;
@@ -914,6 +895,32 @@
 
         mShowWhenLocked = (aInfo.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
         mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
+
+        mRotationAnimationHint = aInfo.rotationAnimation;
+        lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
+        if (appInfo.isPrivilegedApp() && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
+                || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
+            lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
+        }
+
+        if (options != null) {
+            pendingOptions = options;
+            mLaunchTaskBehind = options.getLaunchTaskBehind();
+
+            final int rotationAnimation = pendingOptions.getRotationAnimationHint();
+            // Only override manifest supplied option if set.
+            if (rotationAnimation >= 0) {
+                mRotationAnimationHint = rotationAnimation;
+            }
+            final PendingIntent usageReport = pendingOptions.getUsageTimeReport();
+            if (usageReport != null) {
+                appTimeTracker = new AppTimeTracker(usageReport);
+            }
+            final boolean useLockTask = pendingOptions.getLockTaskMode();
+            if (useLockTask && lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_DEFAULT) {
+                lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
+            }
+        }
     }
 
     AppWindowContainerController getWindowContainerController() {
@@ -948,7 +955,7 @@
         // update the initial multi-window modes so that the callbacks are scheduled correctly when
         // the user leaves that mode.
         mLastReportedMultiWindowMode = !task.mFullscreen;
-        mLastReportedPictureInPictureMode = (task.getStackId() == PINNED_STACK_ID);
+        mLastReportedPictureInPictureMode = inPinnedWindowingMode();
     }
 
     void removeWindowContainer() {
@@ -1551,7 +1558,7 @@
             // On devices that support leanback only (Android TV), Recents activity can only be
             // visible if the home stack is the focused stack or we are in split-screen mode.
             final ActivityDisplay display = getDisplay();
-            boolean hasSplitScreenStack = display != null && display.hasSplitScreenStack();
+            boolean hasSplitScreenStack = display != null && display.hasSplitScreenPrimaryStack();
             isVisible = hasSplitScreenStack || mStackSupervisor.isFocusedStack(getStack());
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 1940ca2..f0811dd 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -16,27 +16,25 @@
 
 package com.android.server.am;
 
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.app.WindowConfiguration.activityTypeToString;
+import static android.app.WindowConfiguration.windowingModeToString;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
 import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
-
 import static android.view.Display.INVALID_DISPLAY;
+
 import static com.android.server.am.ActivityDisplay.POSITION_BOTTOM;
 import static com.android.server.am.ActivityDisplay.POSITION_TOP;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
@@ -100,7 +98,6 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityManager.StackId;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityController;
@@ -110,6 +107,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.res.Configuration;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Binder;
@@ -192,10 +190,6 @@
     // finished destroying itself.
     private static final int DESTROY_TIMEOUT = 10 * 1000;
 
-    // How long until we reset a task when the user returns to it.  Currently
-    // disabled.
-    private static final long ACTIVITY_INACTIVE_RESET_TIME = 0;
-
     // Set to false to disable the preview that is shown while a new activity
     // is being started.
     private static final boolean SHOW_APP_STARTING_PREVIEW = true;
@@ -352,12 +346,11 @@
     private final SparseArray<Rect> mTmpBounds = new SparseArray<>();
     private final SparseArray<Rect> mTmpInsetBounds = new SparseArray<>();
     private final Rect mTmpRect2 = new Rect();
+    private final Point mTmpSize = new Point();
 
     /** Run all ActivityStacks through this */
     protected final ActivityStackSupervisor mStackSupervisor;
 
-    private final LaunchingTaskPositioner mTaskPositioner;
-
     private boolean mTopActivityOccludesKeyguard;
     private ActivityRecord mTopDismissingKeyguardActivity;
 
@@ -460,8 +453,6 @@
         mWindowManager = mService.mWindowManager;
         mStackId = stackId;
         mCurrentUser = mService.mUserController.getCurrentUserId();
-        mTaskPositioner = mStackId == FREEFORM_WORKSPACE_STACK_ID
-                ? new LaunchingTaskPositioner() : null;
         mTmpRect2.setEmpty();
         setWindowingMode(windowingMode);
         setActivityType(activityType);
@@ -479,6 +470,16 @@
         return mWindowContainerController;
     }
 
+    @Override
+    public void onConfigurationChanged(Configuration newParentConfig) {
+        final int prevWindowingMode = getWindowingMode();
+        super.onConfigurationChanged(newParentConfig);
+        final ActivityDisplay display = getDisplay();
+        if (display != null && prevWindowingMode != getWindowingMode()) {
+            display.onStackWindowingModeChanged(this);
+        }
+    }
+
     /** Adds the stack to specified display and calls WindowManager to do the same. */
     void reparent(ActivityDisplay activityDisplay, boolean onTop) {
         removeFromDisplay();
@@ -502,14 +503,11 @@
         mDisplayId = activityDisplay.mDisplayId;
         mBounds = bounds != null ? new Rect(bounds) : null;
         mFullscreen = mBounds == null;
-        if (mTaskPositioner != null) {
-            mTaskPositioner.setDisplay(activityDisplay.mDisplay);
-            mTaskPositioner.configure(mBounds);
-        }
+
         onParentChanged();
 
         activityDisplay.addChild(this, onTop ? POSITION_TOP : POSITION_BOTTOM);
-        if (mStackId == DOCKED_STACK_ID) {
+        if (inSplitScreenPrimaryWindowingMode()) {
             // If we created a docked stack we want to resize it so it resizes all other stacks
             // in the system.
             mStackSupervisor.resizeDockedStackLocked(
@@ -533,9 +531,6 @@
             display.removeChild(this);
         }
         mDisplayId = INVALID_DISPLAY;
-        if (mTaskPositioner != null) {
-            mTaskPositioner.reset();
-        }
     }
 
     /** Removes the stack completely. Also calls WindowManager to do the same on its side. */
@@ -639,9 +634,6 @@
 
     void setBounds(Rect bounds) {
         mBounds = mFullscreen ? null : new Rect(bounds);
-        if (mTaskPositioner != null) {
-            mTaskPositioner.configure(bounds);
-        }
     }
 
     ActivityRecord topRunningActivityLocked() {
@@ -818,14 +810,6 @@
         return isActivityTypeHome() || isActivityTypeRecents();
     }
 
-    final boolean isDockedStack() {
-        return mStackId == DOCKED_STACK_ID;
-    }
-
-    final boolean isPinnedStack() {
-        return mStackId == PINNED_STACK_ID;
-    }
-
     final boolean isOnHomeDisplay() {
         return mDisplayId == DEFAULT_DISPLAY;
     }
@@ -1505,9 +1489,9 @@
      * needed. A stack is considered translucent if it don't contain a visible or
      * starting (about to be visible) activity that is fullscreen (opaque).
      * @param starting The currently starting activity or null if there is none.
-     * @param stackBehindId The id of the stack directly behind this one.
+     * @param stackBehind The stack directly behind this one.
      */
-    private boolean isStackTranslucent(ActivityRecord starting, int stackBehindId) {
+    private boolean isStackTranslucent(ActivityRecord starting, ActivityStack stackBehind) {
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             final TaskRecord task = mTaskHistory.get(taskNdx);
             final ArrayList<ActivityRecord> activities = task.mActivities;
@@ -1532,7 +1516,6 @@
                     return false;
                 }
 
-                final ActivityStack stackBehind = mStackSupervisor.getStack(stackBehindId);
                 final boolean stackBehindHomeOrRecent = stackBehind != null
                         && stackBehind.isHomeOrRecentsStack();
                 if (!isHomeOrRecentsStack() && r.frontOfTask && task.isOverHomeStack()
@@ -1553,6 +1536,10 @@
                 && !mForceHidden;
     }
 
+    boolean isTopStackOnDisplay() {
+        return getDisplay().isTopStack(this);
+    }
+
     /**
      * Returns true if the stack should be visible.
      *
@@ -1563,23 +1550,15 @@
             return false;
         }
 
-        if (mStackSupervisor.isFrontStackOnDisplay(this) || mStackSupervisor.isFocusedStack(this)) {
+        final ActivityDisplay display = getDisplay();
+        if (isTopStackOnDisplay() || mStackSupervisor.isFocusedStack(this)) {
             return true;
         }
 
-        final ActivityDisplay display = getDisplay();
-        final ArrayList<ActivityStack> displayStacks = display.mStacks;
-        final int stackIndex = displayStacks.indexOf(this);
-
-        if (stackIndex == displayStacks.size() - 1) {
-            Slog.wtf(TAG,
-                    "Stack=" + this + " isn't front stack but is at the top of the stack list");
-            return false;
-        }
+        final int stackIndex = display.getIndexOf(this);
 
         // Check position and visibility of this stack relative to the front stack on its display.
-        final ActivityStack topStack = getTopStackOnDisplay();
-        final int topStackId = topStack.mStackId;
+        final ActivityStack topStack = getDisplay().getTopStack();
         final int windowingMode = getWindowingMode();
         final int activityType = getActivityType();
 
@@ -1587,7 +1566,7 @@
             // If the assistant stack is focused and translucent, then the docked stack is always
             // visible
             if (topStack.isActivityTypeAssistant()) {
-                return topStack.isStackTranslucent(starting, DOCKED_STACK_ID);
+                return topStack.isStackTranslucent(starting, this);
             }
             return true;
         }
@@ -1596,34 +1575,31 @@
         // A case would be if recents stack exists but has no tasks and is below the docked stack
         // and home stack is below recents
         if (activityType == ACTIVITY_TYPE_HOME) {
-            final ActivityStack splitScreenStack = display.getStack(
-                    WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
-            int dockedStackIndex = displayStacks.indexOf(splitScreenStack);
+            final ActivityStack splitScreenStack = display.getSplitScreenPrimaryStack();
+            int dockedStackIndex = display.getIndexOf(splitScreenStack);
             if (dockedStackIndex > stackIndex && stackIndex != dockedStackIndex - 1) {
                 return false;
             }
         }
 
         // Find the first stack behind front stack that actually got something visible.
-        int stackBehindTopIndex = displayStacks.indexOf(topStack) - 1;
+        int stackBehindTopIndex = display.getIndexOf(topStack) - 1;
         while (stackBehindTopIndex >= 0 &&
-                displayStacks.get(stackBehindTopIndex).topRunningActivityLocked() == null) {
+                display.getChildAt(stackBehindTopIndex).topRunningActivityLocked() == null) {
             stackBehindTopIndex--;
         }
         final ActivityStack stackBehindTop = (stackBehindTopIndex >= 0)
-                ? displayStacks.get(stackBehindTopIndex) : null;
-        int stackBehindTopId = INVALID_STACK_ID;
+                ? display.getChildAt(stackBehindTopIndex) : null;
         int stackBehindTopWindowingMode = WINDOWING_MODE_UNDEFINED;
         int stackBehindTopActivityType = ACTIVITY_TYPE_UNDEFINED;
         if (stackBehindTop != null) {
-            stackBehindTopId = stackBehindTop.mStackId;
             stackBehindTopWindowingMode = stackBehindTop.getWindowingMode();
             stackBehindTopActivityType = stackBehindTop.getActivityType();
         }
 
         final boolean alwaysOnTop = topStack.getWindowConfiguration().isAlwaysOnTop();
         if (topStack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || alwaysOnTop) {
-            if (stackIndex == stackBehindTopIndex) {
+            if (this == stackBehindTop) {
                 // Stacks directly behind the docked or pinned stack are always visible.
                 return true;
             } else if (alwaysOnTop && stackIndex == stackBehindTopIndex - 1) {
@@ -1632,14 +1608,13 @@
                 if (stackBehindTopWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
                     return true;
                 } else if (stackBehindTopActivityType == ACTIVITY_TYPE_ASSISTANT) {
-                    return displayStacks.get(stackBehindTopIndex).isStackTranslucent(
-                            starting, mStackId);
+                    return stackBehindTop.isStackTranslucent(starting, this);
                 }
             }
         }
 
         if (topStack.isBackdropToTranslucentActivity()
-                && topStack.isStackTranslucent(starting, stackBehindTopId)) {
+                && topStack.isStackTranslucent(starting, stackBehindTop)) {
             // Stacks behind the fullscreen or assistant stack with a translucent activity are
             // always visible so they can act as a backdrop to the translucent activity.
             // For example, dialog activities
@@ -1657,14 +1632,15 @@
             }
         }
 
-        if (StackId.isStaticStack(mStackId)
-                || isHomeOrRecentsStack() || isActivityTypeAssistant()) {
-            // Visibility of any static stack should have been determined by the conditions above.
+        if (isOnHomeDisplay()) {
+            // Visibility of any stack on default display should have been determined by the
+            // conditions above.
             return false;
         }
 
-        for (int i = stackIndex + 1; i < displayStacks.size(); i++) {
-            final ActivityStack stack = displayStacks.get(i);
+        final int stackCount = display.getChildCount();
+        for (int i = stackIndex + 1; i < stackCount; i++) {
+            final ActivityStack stack = display.getChildAt(i);
 
             if (!stack.mFullscreen && !stack.hasFullscreenTask()) {
                 continue;
@@ -1675,7 +1651,7 @@
                 return false;
             }
 
-            if (!stack.isStackTranslucent(starting, INVALID_STACK_ID)) {
+            if (!stack.isStackTranslucent(starting, null /* stackBehind */)) {
                 return false;
             }
         }
@@ -1801,7 +1777,8 @@
                         makeInvisible(r);
                     }
                 }
-                if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+                final int windowingMode = getWindowingMode();
+                if (windowingMode == WINDOWING_MODE_FREEFORM) {
                     // The visibility of tasks and the activities they contain in freeform stack are
                     // determined individually unlike other stacks where the visibility or fullscreen
                     // status of an activity in a previous task affects other.
@@ -1816,7 +1793,8 @@
                     // show activities in the next application stack behind them vs. another
                     // task in the home stack like recents.
                     behindFullscreenActivity = true;
-                } else if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
+                } else if (windowingMode == WINDOWING_MODE_FULLSCREEN
+                        || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
                     if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping after task=" + task
                             + " returning to non-application type=" + task.getTaskToReturnTo());
                     // Once we reach a fullscreen stack task that has a running activity and should
@@ -1852,6 +1830,32 @@
     }
 
     /**
+     * Returns true if this stack should be resized to match the bounds specified by
+     * {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack.
+     */
+    boolean resizeStackWithLaunchBounds() {
+        return inPinnedWindowingMode();
+    }
+
+    /**
+     * Returns true if we try to maintain focus in the current stack when the top activity finishes.
+     */
+    private boolean keepFocusInStackIfPossible() {
+        final int windowingMode = getWindowingMode();
+        return windowingMode == WINDOWING_MODE_FREEFORM
+                || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
+                || windowingMode == WINDOWING_MODE_PINNED;
+    }
+
+    /**
+     * Returns true if the top task in the task is allowed to return home when finished and
+     * there are other tasks in the stack.
+     */
+    boolean allowTopTaskToReturnHome() {
+        return !inPinnedWindowingMode();
+    }
+
+    /**
      * @return the top most visible activity that wants to dismiss Keyguard
      */
     ActivityRecord getTopDismissingKeyguardActivity() {
@@ -1867,7 +1871,7 @@
      */
     boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible,
             boolean isTop) {
-        final boolean isInPinnedStack = r.getStack().getStackId() == PINNED_STACK_ID;
+        final boolean isInPinnedStack = r.inPinnedWindowingMode();
         final boolean keyguardShowing = mStackSupervisor.mKeyguardController.isKeyguardShowing(
                 mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY);
         final boolean keyguardLocked = mStackSupervisor.mKeyguardController.isKeyguardLocked();
@@ -2165,7 +2169,7 @@
         mResumedActivity = r;
         r.state = ActivityState.RESUMED;
         mService.setResumedActivityUncheckLocked(r, reason);
-        mStackSupervisor.addRecentActivity(r);
+        mStackSupervisor.mRecentTasks.add(r.getTask());
     }
 
     private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
@@ -2572,8 +2576,8 @@
                     Slog.i(TAG, "Restarting because process died: " + next);
                     if (!next.hasBeenLaunched) {
                         next.hasBeenLaunched = true;
-                    } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
-                            mStackSupervisor.isFrontStackOnDisplay(lastStack)) {
+                    } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null
+                            && lastStack.isTopStackOnDisplay()) {
                         next.showStartingWindow(null /* prev */, false /* newTask */,
                                 false /* taskSwitch */);
                     }
@@ -2617,7 +2621,7 @@
 
     private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
             ActivityOptions options, String reason) {
-        if ((!mFullscreen || !isOnHomeDisplay()) && adjustFocusToNextFocusableStackLocked(reason)) {
+        if (adjustFocusToNextFocusableStackLocked(reason)) {
             // Try to move focus to the next visible stack with a running activity if this
             // stack is not covering the entire screen or is on a secondary display (with no home
             // stack).
@@ -2746,9 +2750,8 @@
             // make underlying task focused when this one will be finished.
             int returnToType = isLastTaskOverHome
                     ? task.getTaskToReturnTo() : ACTIVITY_TYPE_STANDARD;
-            if (fromHomeOrRecents && StackId.allowTopTaskToReturnHome(mStackId)) {
-                returnToType = topTask == null
-                        ? ACTIVITY_TYPE_HOME : topTask.getActivityType();
+            if (fromHomeOrRecents && allowTopTaskToReturnHome()) {
+                returnToType = topTask == null ? ACTIVITY_TYPE_HOME : topTask.getActivityType();
             }
             task.setTaskToReturnTo(returnToType);
         }
@@ -2901,7 +2904,7 @@
             // Ensure the caller has requested not to trigger auto-enter PiP
             return false;
         }
-        if (pipCandidate == null || pipCandidate.getStackId() == PINNED_STACK_ID) {
+        if (pipCandidate == null || pipCandidate.inPinnedWindowingMode()) {
             // Ensure that we do not trigger entering PiP an activity on the pinned stack
             return false;
         }
@@ -3186,15 +3189,8 @@
 
     final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
             ActivityRecord newActivity) {
-        boolean forceReset =
+        final boolean forceReset =
                 (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
-        if (ACTIVITY_INACTIVE_RESET_TIME > 0
-                && taskTop.getTask().getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
-            if ((newActivity.info.flags & ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
-                forceReset = true;
-            }
-        }
-
         final TaskRecord task = taskTop.getTask();
 
         /** False until we evaluate the TaskRecord associated with taskTop. Switches to true
@@ -3291,7 +3287,7 @@
         final String myReason = reason + " adjustFocus";
 
         if (next != r) {
-            if (next != null && StackId.keepFocusInStackIfPossible(mStackId) && isFocusable()) {
+            if (next != null && keepFocusInStackIfPossible() && isFocusable()) {
                 // For freeform, docked, and pinned stacks we always keep the focus within the
                 // stack as long as there is a running activity.
                 return;
@@ -3757,7 +3753,7 @@
 
         if (mode == FINISH_IMMEDIATELY
                 || (prevState == ActivityState.PAUSED
-                    && (mode == FINISH_AFTER_PAUSE || mStackId == PINNED_STACK_ID))
+                    && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
                 || finishingActivityInNonFocusedStack
                 || prevState == STOPPING
                 || prevState == STOPPED
@@ -4436,7 +4432,7 @@
             AppTimeTracker timeTracker, String reason) {
         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
 
-        final ActivityStack topStack = getTopStackOnDisplay();
+        final ActivityStack topStack = getDisplay().getTopStack();
         final ActivityRecord topActivity = topStack != null ? topStack.topActivity() : null;
         final int numTasks = mTaskHistory.size();
         final int index = mTaskHistory.indexOf(tr);
@@ -4464,7 +4460,9 @@
         // Don't refocus if invisible to current user
         final ActivityRecord top = tr.getTopActivity();
         if (top == null || !top.okToShowLocked()) {
-            mStackSupervisor.addRecentActivity(top);
+            if (top != null) {
+                mStackSupervisor.mRecentTasks.add(top.getTask());
+            }
             ActivityOptions.abort(options);
             return;
         }
@@ -4524,7 +4522,7 @@
         // If we have a watcher, preflight the move before committing to it.  First check
         // for *other* available tasks, but if none are available, then try again allowing the
         // current task to be selected.
-        if (mStackSupervisor.isFrontStackOnDisplay(this) && mService.mController != null) {
+        if (isTopStackOnDisplay() && mService.mController != null) {
             ActivityRecord next = topRunningActivityLocked(null, taskId);
             if (next == null) {
                 next = topRunningActivityLocked(null, 0);
@@ -4571,8 +4569,8 @@
             mWindowContainerController.positionChildAtBottom(tr.getWindowContainerController());
         }
 
-        if (mStackId == PINNED_STACK_ID) {
-            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
+        if (inPinnedWindowingMode()) {
+            mStackSupervisor.removeStack(this);
             return true;
         }
 
@@ -4604,15 +4602,6 @@
         return true;
     }
 
-    /**
-     * Get the topmost stack on the current display. It may be different from focused stack, because
-     * focus may be on another display.
-     */
-    private ActivityStack getTopStackOnDisplay() {
-        final ArrayList<ActivityStack> stacks = getDisplay().mStacks;
-        return stacks.isEmpty() ? null : stacks.get(stacks.size() - 1);
-    }
-
     static void logStartActivity(int tag, ActivityRecord r, TaskRecord task) {
         final Uri data = r.intent.getData();
         final String strData = data != null ? data.toSafeString() : null;
@@ -4687,7 +4676,7 @@
         for (int i = mTaskHistory.size() - 1; i >= 0; i--) {
             final TaskRecord task = mTaskHistory.get(i);
             if (task.isResizeable()) {
-                if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+                if (inFreeformWindowingMode()) {
                     // For freeform stack we don't adjust the size of the tasks to match that
                     // of the stack, but we do try to make sure the tasks are still contained
                     // with the bounds of the stack.
@@ -4889,7 +4878,7 @@
             if (focusedStack && topTask) {
                 // Give the latest time to ensure foreground task can be sorted
                 // at the first, because lastActiveTime of creating task is 0.
-                ci.lastActiveTime = System.currentTimeMillis();
+                ci.lastActiveTime = SystemClock.elapsedRealtime();
                 topTask = false;
             }
 
@@ -5069,7 +5058,7 @@
             if (task.autoRemoveFromRecents() || isVoiceSession) {
                 // Task creator asked to remove this when done, or this task was a voice
                 // interaction, so it should not remain on the recent tasks list.
-                mStackSupervisor.removeTaskFromRecents(task);
+                mStackSupervisor.mRecentTasks.remove(task);
             }
 
             task.removeWindowContainer();
@@ -5097,7 +5086,7 @@
         task.setStack(null);
 
         // Notify if a task from the pinned stack is being removed (or moved depending on the mode)
-        if (mStackId == PINNED_STACK_ID) {
+        if (inPinnedWindowingMode()) {
             mService.mTaskChangeNotificationController.notifyActivityUnpinned();
         }
     }
@@ -5120,10 +5109,12 @@
     }
 
     boolean layoutTaskInStack(TaskRecord task, ActivityInfo.WindowLayout windowLayout) {
-        if (mTaskPositioner == null) {
+        if (!task.inFreeformWindowingMode()) {
             return false;
         }
-        mTaskPositioner.updateDefaultBounds(task, mTaskHistory, windowLayout);
+        mStackSupervisor.getLaunchingTaskPositioner()
+                .updateDefaultBounds(task, mTaskHistory, windowLayout);
+
         return true;
     }
 
@@ -5248,10 +5239,12 @@
     @Override
     public String toString() {
         return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this))
-                + " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}";
+                + " stackId=" + mStackId + " type=" + activityTypeToString(getActivityType())
+                + " mode=" + windowingModeToString(getWindowingMode()) + ", "
+                + mTaskHistory.size() + " tasks}";
     }
 
-    void onLockTaskPackagesUpdatedLocked() {
+    void onLockTaskPackagesUpdated() {
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             mTaskHistory.get(taskNdx).setLockTaskAuth();
         }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index da2827a..5c91e3c 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -21,11 +21,7 @@
 import static android.Manifest.permission.START_ANY_ACTIVITY;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
@@ -35,10 +31,13 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.app.WindowConfiguration.activityTypeToString;
+import static android.app.WindowConfiguration.windowingModeToString;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
@@ -47,6 +46,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.Display.TYPE_VIRTUAL;
+
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
@@ -86,12 +86,13 @@
 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
 import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
+import static com.android.server.am.proto.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
 import static com.android.server.am.proto.ActivityStackSupervisorProto.DISPLAYS;
 import static com.android.server.am.proto.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
 import static com.android.server.am.proto.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
 import static com.android.server.am.proto.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
-import static com.android.server.am.proto.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
 import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
+
 import static java.lang.Integer.MAX_VALUE;
 
 import android.Manifest;
@@ -102,7 +103,6 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityManager.StackId;
 import android.app.ActivityManager.StackInfo;
 import android.app.ActivityManagerInternal.SleepToken;
 import android.app.ActivityOptions;
@@ -176,7 +176,8 @@
 import java.util.List;
 import java.util.Set;
 
-public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
+public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener,
+        RecentTasks.Callbacks {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
     private static final String TAG_IDLE = TAG + POSTFIX_IDLE;
@@ -286,7 +287,7 @@
 
     final ActivityManagerService mService;
 
-    private RecentTasks mRecentTasks;
+    RecentTasks mRecentTasks;
 
     final ActivityStackSupervisorHandler mHandler;
 
@@ -294,8 +295,10 @@
     WindowManagerService mWindowManager;
     DisplayManager mDisplayManager;
 
+    LaunchingTaskPositioner mTaskPositioner = new LaunchingTaskPositioner();
+
     /** Counter for next free stack ID to use for dynamic activity stacks. */
-    private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID;
+    private int mNextFreeStackId = 0;
 
     /**
      * Maps the task identifier that activities are currently being started in to the userId of the
@@ -576,6 +579,7 @@
 
     void setRecentTasks(RecentTasks recentTasks) {
         mRecentTasks = recentTasks;
+        mRecentTasks.registerCallback(this);
     }
 
     /**
@@ -627,15 +631,6 @@
         return stack != null && stack == mFocusedStack;
     }
 
-    /** The top most stack on its display. */
-    boolean isFrontStackOnDisplay(ActivityStack stack) {
-        return isFrontOfStackList(stack, stack.getDisplay().mStacks);
-    }
-
-    private boolean isFrontOfStackList(ActivityStack stack, List<ActivityStack> stackList) {
-        return stack == stackList.get((stackList.size() - 1));
-    }
-
     /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */
     void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) {
         if (!focusCandidate.isFocusable()) {
@@ -731,9 +726,9 @@
 
         int numDisplays = mActivityDisplays.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 final TaskRecord task = stack.taskForIdLocked(id);
                 if (task != null) {
                     return task;
@@ -749,7 +744,7 @@
         // Otherwise, check the recent tasks and return if we find it there and we are not restoring
         // the task from recents
         if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
-        final TaskRecord task = mRecentTasks.taskForIdLocked(id);
+        final TaskRecord task = mRecentTasks.getTask(id);
 
         if (task == null) {
             if (DEBUG_RECENTS) {
@@ -776,9 +771,10 @@
     ActivityRecord isInAnyStackLocked(IBinder token) {
         int numDisplays = mActivityDisplays.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
+                final ActivityRecord r = stack.isInStackLocked(token);
                 if (r != null) {
                     return r;
                 }
@@ -816,18 +812,21 @@
     void lockAllProfileTasks(@UserIdInt int userId) {
         mWindowManager.deferSurfaceLayout();
         try {
-            final List<ActivityStack> stacks = getStacks();
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; stackNdx--) {
-                final List<TaskRecord> tasks = stacks.get(stackNdx).getAllTasks();
-                for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
-                    final TaskRecord task = tasks.get(taskNdx);
+            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
+                final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+                for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                    final ActivityStack stack = display.getChildAt(stackNdx);
+                    final List<TaskRecord> tasks = stack.getAllTasks();
+                    for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
+                        final TaskRecord task = tasks.get(taskNdx);
 
-                    // Check the task for a top activity belonging to userId, or returning a result
-                    // to an activity belonging to userId. Example case: a document picker for
-                    // personal files, opened by a work app, should still get locked.
-                    if (taskTopActivityIsUser(task, userId)) {
-                        mService.mTaskChangeNotificationController.notifyTaskProfileLocked(
-                                task.taskId, userId);
+                        // Check the task for a top activity belonging to userId, or returning a
+                        // result to an activity belonging to userId. Example case: a document
+                        // picker for personal files, opened by a work app, should still get locked.
+                        if (taskTopActivityIsUser(task, userId)) {
+                            mService.mTaskChangeNotificationController.notifyTaskProfileLocked(
+                                    task.taskId, userId);
+                        }
                     }
                 }
             }
@@ -858,7 +857,7 @@
         // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER
         // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on.
         int candidateTaskId = nextTaskIdForUser(currentTaskId, userId);
-        while (mRecentTasks.taskIdTakenForUserLocked(candidateTaskId, userId)
+        while (mRecentTasks.containsTaskId(candidateTaskId, userId)
                 || anyTaskForIdLocked(
                         candidateTaskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) != null) {
             candidateTaskId = nextTaskIdForUser(candidateTaskId, userId);
@@ -893,9 +892,9 @@
         final String processName = app.processName;
         boolean didSomething = false;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 if (!isFocusedStack(stack)) {
                     continue;
                 }
@@ -928,9 +927,9 @@
 
     boolean allResumedActivitiesIdle() {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 if (!isFocusedStack(stack) || stack.numActivities() == 0) {
                     continue;
                 }
@@ -949,9 +948,9 @@
 
     boolean allResumedActivitiesComplete() {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 if (isFocusedStack(stack)) {
                     final ActivityRecord r = stack.mResumedActivity;
                     if (r != null && r.state != RESUMED) {
@@ -968,12 +967,12 @@
         return true;
     }
 
-    boolean allResumedActivitiesVisible() {
+    private boolean allResumedActivitiesVisible() {
         boolean foundResumed = false;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 final ActivityRecord r = stack.mResumedActivity;
                 if (r != null) {
                     if (!r.nowVisible || mActivitiesWaitingForVisibleActivity.contains(r)) {
@@ -997,9 +996,9 @@
     boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
         boolean someActivityPaused = false;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 if (!isFocusedStack(stack) && stack.mResumedActivity != null) {
                     if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
                             " mResumedActivity=" + stack.mResumedActivity);
@@ -1014,9 +1013,9 @@
     boolean allPausedActivitiesComplete() {
         boolean pausing = true;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 final ActivityRecord r = stack.mPausingActivity;
                 if (r != null && r.state != PAUSED && r.state != STOPPED && r.state != STOPPING) {
                     if (DEBUG_STATES) {
@@ -1034,9 +1033,10 @@
 
     void cancelInitializingActivities() {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                stacks.get(stackNdx).cancelInitializingActivities();
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
+                stack.cancelInitializingActivities();
             }
         }
     }
@@ -1134,13 +1134,10 @@
 
         for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
             final int displayId = mTmpOrderedDisplayIds.get(i);
-            final List<ActivityStack> stacks = mActivityDisplays.get(displayId).mStacks;
-            if (stacks == null) {
-                continue;
-            }
-            for (int j = stacks.size() - 1; j >= 0; --j) {
-                final ActivityStack stack = stacks.get(j);
-                if (stack != focusedStack && isFrontStackOnDisplay(stack) && stack.isFocusable()) {
+            final ActivityDisplay display = mActivityDisplays.get(displayId);
+            for (int j = display.getChildCount() - 1; j >= 0; --j) {
+                final ActivityStack stack = display.getChildAt(j);
+                if (stack != focusedStack && stack.isTopStackOnDisplay() && stack.isFocusable()) {
                     r = stack.topRunningActivityLocked();
                     if (r != null) {
                         return r;
@@ -1156,9 +1153,9 @@
         ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists = new ArrayList<>();
         final int numDisplays = mActivityDisplays.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<>();
                 runningTaskLists.add(stackTaskList);
                 stack.getTasksLocked(stackTaskList, callingUid, allowed);
@@ -1607,6 +1604,16 @@
                 Slog.w(TAG, msg);
                 throw new SecurityException(msg);
             }
+            // Check if someone tries to launch an unwhitelisted activity into LockTask mode.
+            final boolean lockTaskMode = options.getLockTaskMode();
+            if (lockTaskMode && !mService.mLockTaskController.isPackageWhitelisted(
+                    UserHandle.getUserId(callingUid), aInfo.packageName)) {
+                final String msg = "Permission Denial: starting " + intent.toString()
+                        + " from " + callerApp + " (pid=" + callingPid
+                        + ", uid=" + callingUid + ") with lockTaskMode=true";
+                Slog.w(TAG, msg);
+                throw new SecurityException(msg);
+            }
         }
 
         return true;
@@ -1928,9 +1935,10 @@
     boolean handleAppDiedLocked(ProcessRecord app) {
         boolean hasVisibleActivities = false;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
+                hasVisibleActivities |= stack.handleAppDiedLocked(app);
             }
         }
         return hasVisibleActivities;
@@ -1938,9 +1946,10 @@
 
     void closeSystemDialogsLocked() {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                stacks.get(stackNdx).closeSystemDialogsLocked();
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
+                stack.closeSystemDialogsLocked();
             }
         }
     }
@@ -1966,9 +1975,9 @@
             boolean doit, boolean evenPersistent, int userId) {
         boolean didSomething = false;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 if (stack.finishDisabledPackageActivitiesLocked(
                         packageName, filterByClasses, doit, evenPersistent, userId)) {
                     didSomething = true;
@@ -1988,9 +1997,9 @@
         // hosted by the process that is actually still the foreground.
         ProcessRecord fgApp = null;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 if (isFocusedStack(stack)) {
                     if (stack.mResumedActivity != null) {
                         fgApp = stack.mResumedActivity.app;
@@ -2040,9 +2049,10 @@
 
     void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                stacks.get(stackNdx).updateActivityApplicationInfoLocked(aInfo);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
+                stack.updateActivityApplicationInfoLocked(aInfo);
             }
         }
     }
@@ -2051,10 +2061,10 @@
         TaskRecord finishedTask = null;
         ActivityStack focusedStack = getFocusedStack();
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            final int numStacks = stacks.size();
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            final int numStacks = display.getChildCount();
             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 TaskRecord t = stack.finishTopRunningActivityLocked(app, reason);
                 if (stack == focusedStack || finishedTask == null) {
                     finishedTask = t;
@@ -2066,10 +2076,10 @@
 
     void finishVoiceTask(IVoiceInteractionSession session) {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            final int numStacks = stacks.size();
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            final int numStacks = display.getChildCount();
             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 stack.finishVoiceTask(session);
             }
         }
@@ -2105,8 +2115,8 @@
                 // moveTaskToStackUncheckedLocked() should already placed the task on top,
                 // still need moveTaskToFrontLocked() below for any transition settings.
             }
-            if (StackId.resizeStackWithLaunchBounds(stack.mStackId)) {
-                resizeStackLocked(stack.mStackId, bounds, null /* tempTaskBounds */,
+            if (stack.resizeStackWithLaunchBounds()) {
+                resizeStackLocked(stack, bounds, null /* tempTaskBounds */,
                         null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
                         true /* allowResizeInDockedMode */, !DEFER_RESUME);
             } else {
@@ -2125,7 +2135,7 @@
                 "findTaskToMoveToFront: moved to front of stack=" + currentStack);
 
         handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY,
-                currentStack.mStackId, forceNonResizeable);
+                currentStack, forceNonResizeable);
     }
 
     boolean canUseActivityOptionsLaunchBounds(ActivityOptions options) {
@@ -2139,6 +2149,10 @@
                 || mService.mSupportsFreeformWindowManagement;
     }
 
+    LaunchingTaskPositioner getLaunchingTaskPositioner() {
+        return mTaskPositioner;
+    }
+
     protected <T extends ActivityStack> T getStack(int stackId) {
         for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
             final T stack = mActivityDisplays.valueAt(i).getStack(stackId);
@@ -2316,8 +2330,8 @@
             }
             final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId);
             if (display != null) {
-                for (int i = display.mStacks.size() - 1; i >= 0; --i) {
-                    stack = (T) display.mStacks.get(i);
+                for (int i = display.getChildCount() - 1; i >= 0; --i) {
+                    stack = (T) display.getChildAt(i);
                     if (stack.isCompatible(windowingMode, activityType)) {
                         return stack;
                     }
@@ -2385,8 +2399,8 @@
         }
 
         // Return the topmost valid stack on the display.
-        for (int i = activityDisplay.mStacks.size() - 1; i >= 0; --i) {
-            final ActivityStack stack = activityDisplay.mStacks.get(i);
+        for (int i = activityDisplay.getChildCount() - 1; i >= 0; --i) {
+            final ActivityStack stack = activityDisplay.getChildAt(i);
             if (isValidLaunchStack(stack, displayId, r)) {
                 return stack;
             }
@@ -2417,25 +2431,13 @@
             case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: return r.supportsSplitScreenWindowingMode();
         }
 
-        if (StackId.isDynamicStack(stack.mStackId)) {
+        if (!stack.isOnHomeDisplay()) {
             return r.canBeLaunchedOnDisplay(displayId);
         }
         Slog.e(TAG, "isValidLaunchStack: Unexpected stack=" + stack);
         return false;
     }
 
-    ArrayList<ActivityStack> getStacks() {
-        ArrayList<ActivityStack> allStacks = new ArrayList<>();
-        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
-        }
-        return allStacks;
-    }
-
-    ArrayList<ActivityStack> getStacksOnDefaultDisplay() {
-        return mActivityDisplays.valueAt(DEFAULT_DISPLAY).mStacks;
-    }
-
     /**
      * Get next focusable stack in the system. This will search across displays and stacks
      * in last-focused order for a focusable and visible stack, different from the target stack.
@@ -2450,10 +2452,9 @@
         for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
             final int displayId = mTmpOrderedDisplayIds.get(i);
             // If a display is registered in WM, it must also be available in AM.
-            @SuppressWarnings("ConstantConditions")
-            final List<ActivityStack> stacks = getActivityDisplayOrCreateLocked(displayId).mStacks;
-            for (int j = stacks.size() - 1; j >= 0; --j) {
-                final ActivityStack stack = stacks.get(j);
+            final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId);
+            for (int j = display.getChildCount() - 1; j >= 0; --j) {
+                final ActivityStack stack = display.getChildAt(j);
                 if (stack != currentFocus && stack.isFocusable()
                         && stack.shouldBeVisible(null)) {
                     return stack;
@@ -2511,20 +2512,17 @@
         return null;
     }
 
-    void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
-            boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) {
-        if (stackId == DOCKED_STACK_ID) {
+    void resizeStackLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds,
+            Rect tempTaskInsetBounds, boolean preserveWindows, boolean allowResizeInDockedMode,
+            boolean deferResume) {
+
+        if (stack.inSplitScreenPrimaryWindowingMode()) {
             resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null,
                     preserveWindows, deferResume);
             return;
         }
-        final ActivityStack stack = getStack(stackId);
-        if (stack == null) {
-            Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
-            return;
-        }
 
-        final boolean splitScreenActive = getDefaultDisplay().hasSplitScreenStack();
+        final boolean splitScreenActive = getDefaultDisplay().hasSplitScreenPrimaryStack();
         if (!allowResizeInDockedMode
                 && !stack.getWindowConfiguration().tasksAreFloating() && splitScreenActive) {
             // If the docked stack exists, don't resize non-floating stacks independently of the
@@ -2532,7 +2530,7 @@
             return;
         }
 
-        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId);
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stack.mStackId);
         mWindowManager.deferSurfaceLayout();
         try {
             if (stack.supportsSplitScreenWindowingMode()) {
@@ -2584,8 +2582,7 @@
 
     /**
      * TODO: This should just change the windowing mode and resize vs. actually moving task around.
-     * Can do that once we are no longer using static stack ids. Specially when
-     * {@link ActivityManager.StackId#FULLSCREEN_WORKSPACE_STACK_ID} is removed.
+     * Can do that once we are no longer using static stack ids.
      */
     private void moveTasksToFullscreenStackInSurfaceTransaction(ActivityStack fromStack,
             int toDisplayId, boolean onTop) {
@@ -2600,13 +2597,12 @@
                 // We are moving all tasks from the docked stack to the fullscreen stack,
                 // which is dismissing the docked stack, so resize all other stacks to
                 // fullscreen here already so we don't end up with resize trashing.
-                final ArrayList<ActivityStack> displayStacks = toDisplay.mStacks;
-                for (int i = displayStacks.size() - 1; i >= 0; --i) {
-                    final ActivityStack otherStack = displayStacks.get(i);
+                for (int i = toDisplay.getChildCount() - 1; i >= 0; --i) {
+                    final ActivityStack otherStack = toDisplay.getChildAt(i);
                     if (!otherStack.inSplitScreenSecondaryWindowingMode()) {
                         continue;
                     }
-                    resizeStackLocked(otherStack.mStackId, null, null, null, PRESERVE_WINDOWS,
+                    resizeStackLocked(otherStack, null, null, null, PRESERVE_WINDOWS,
                             true /* allowResizeInDockedMode */, DEFER_RESUME);
                 }
 
@@ -2697,8 +2693,7 @@
             return;
         }
 
-        final ActivityStack stack = getDefaultDisplay().getStack(
-                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
+        final ActivityStack stack = getDefaultDisplay().getSplitScreenPrimaryStack();
         if (stack == null) {
             Slog.w(TAG, "resizeDockedStackLocked: docked stack not found");
             return;
@@ -2727,10 +2722,10 @@
                 // static stacks need to be adjusted so they don't overlap with the docked stack.
                 // We get the bounds to use from window manager which has been adjusted for any
                 // screen controls and is also the same for all stacks.
-                final ArrayList<ActivityStack> stacks = getStacksOnDefaultDisplay();
+                final ActivityDisplay display = getDefaultDisplay();
                 final Rect otherTaskRect = new Rect();
-                for (int i = stacks.size() - 1; i >= 0; --i) {
-                    final ActivityStack current = stacks.get(i);
+                for (int i = display.getChildCount() - 1; i >= 0; --i) {
+                    final ActivityStack current = display.getChildAt(i);
                     if (current.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
                         continue;
                     }
@@ -2744,7 +2739,7 @@
                             tempRect /* outStackBounds */,
                             otherTaskRect /* outTempTaskBounds */, true /* ignoreVisibility */);
 
-                    resizeStackLocked(current.mStackId, !tempRect.isEmpty() ? tempRect : null,
+                    resizeStackLocked(current, !tempRect.isEmpty() ? tempRect : null,
                             !otherTaskRect.isEmpty() ? otherTaskRect : tempOtherTaskBounds,
                             tempOtherTaskInsetBounds, preserveWindows,
                             true /* allowResizeInDockedMode */, deferResume);
@@ -2762,8 +2757,7 @@
 
     void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
         // TODO(multi-display): Pinned stack display should be passed in.
-        final PinnedActivityStack stack = getDefaultDisplay().getStack(
-                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+        final PinnedActivityStack stack = getDefaultDisplay().getPinnedStack();
         if (stack == null) {
             Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found");
             return;
@@ -2801,12 +2795,7 @@
         }
     }
 
-    private void removeStackInSurfaceTransaction(int stackId) {
-        final ActivityStack stack = getStack(stackId);
-        if (stack == null) {
-            return;
-        }
-
+    private void removeStackInSurfaceTransaction(ActivityStack stack) {
         final ArrayList<TaskRecord> tasks = stack.getAllTasks();
         if (stack.getWindowingMode() == WINDOWING_MODE_PINNED) {
             /**
@@ -2836,12 +2825,12 @@
     }
 
     /**
-     * Removes the stack associated with the given {@param stackId}.  If the {@param stackId} is the
+     * Removes the stack associated with the given {@param stack}. If the {@param stack} is the
      * pinned stack, then its tasks are not explicitly removed when the stack is destroyed, but
      * instead moved back onto the fullscreen stack.
      */
-    void removeStackLocked(int stackId) {
-        mWindowManager.inSurfaceTransaction(() -> removeStackInSurfaceTransaction(stackId));
+    void removeStack(ActivityStack stack) {
+        mWindowManager.inSurfaceTransaction(() -> removeStackInSurfaceTransaction(stack));
     }
 
     /**
@@ -2892,23 +2881,9 @@
         return false;
     }
 
-    void addRecentActivity(ActivityRecord r) {
-        if (r == null) {
-            return;
-        }
-        final TaskRecord task = r.getTask();
-        mRecentTasks.addLocked(task);
-        task.touchActiveTime();
-    }
-
-    void removeTaskFromRecents(TaskRecord task) {
-        mRecentTasks.remove(task);
-        task.removedFromRecents();
-    }
-
     void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess, boolean removeFromRecents) {
         if (removeFromRecents) {
-            removeTaskFromRecents(tr);
+            mRecentTasks.remove(tr);
         }
         ComponentName component = tr.getBaseIntent().getComponent();
         if (component == null) {
@@ -2979,8 +2954,7 @@
 
     int getNextStackId() {
         while (true) {
-            if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID
-                    && getStack(mNextFreeStackId) == null) {
+            if (getStack(mNextFreeStackId) == null) {
                 break;
             }
             mNextFreeStackId++;
@@ -2989,7 +2963,8 @@
     }
 
     /**
-     * Restores a recent task to a stack
+     * Called to restore the state of the task into the stack that it's supposed to go into.
+     *
      * @param task The recent task to be restored.
      * @param aOptions The activity options to use for restoration.
      * @return true if the task has been restored successfully.
@@ -3020,6 +2995,22 @@
         return true;
     }
 
+    @Override
+    public void onRecentTaskAdded(TaskRecord task) {
+        task.touchActiveTime();
+    }
+
+    @Override
+    public void onRecentTaskRemoved(TaskRecord task, boolean wasTrimmed) {
+        if (wasTrimmed) {
+            // Task was trimmed from the recent tasks list -- remove the active task record as well
+            // since the user won't really be able to go back to it
+            removeTaskByIdLocked(task.taskId, false /* killProcess */,
+                    false /* removeFromRecents */);
+        }
+        task.removedFromRecents();
+    }
+
     /**
      * Move stack with all its existing content to specified display.
      * @param stackId Id of stack to move.
@@ -3160,7 +3151,7 @@
             // Resize the pinned stack to match the current size of the task the activity we are
             // going to be moving is currently contained in. We do this to have the right starting
             // animation bounds for the pinned stack to the desired bounds the caller wants.
-            resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */,
+            resizeStackLocked(stack, task.mBounds, null /* tempTaskBounds */,
                     null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
                     true /* allowResizeInDockedMode */, !DEFER_RESUME);
 
@@ -3257,9 +3248,9 @@
         ActivityRecord affinityMatch = null;
         if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 if (!r.hasCompatibleActivityType(stack)) {
                     if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) "
                             + stack);
@@ -3292,12 +3283,13 @@
     }
 
     ActivityRecord findActivityLocked(Intent intent, ActivityInfo info,
-                                      boolean compareIntentFilters) {
+            boolean compareIntentFilters) {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityRecord ar = stacks.get(stackNdx)
-                        .findActivityLocked(intent, info, compareIntentFilters);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
+                final ActivityRecord ar = stack.findActivityLocked(
+                        intent, info, compareIntentFilters);
                 if (ar != null) {
                     return ar;
                 }
@@ -3391,9 +3383,8 @@
             }
 
             // Set the sleeping state of the stacks on the display.
-            final ArrayList<ActivityStack> stacks = display.mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 if (displayShouldSleep) {
                     stack.goToSleepIfPossible(false /* shuttingDown */);
                 } else {
@@ -3455,12 +3446,13 @@
     private boolean putStacksToSleepLocked(boolean allowDelay, boolean shuttingDown) {
         boolean allSleep = true;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 if (allowDelay) {
-                    allSleep &= stacks.get(stackNdx).goToSleepIfPossible(shuttingDown);
+                    allSleep &= stack.goToSleepIfPossible(shuttingDown);
                 } else {
-                    stacks.get(stackNdx).goToSleep();
+                    stack.goToSleep();
                 }
             }
         }
@@ -3485,11 +3477,10 @@
 
     void handleAppCrashLocked(ProcessRecord app) {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            int stackNdx = stacks.size() - 1;
-            while (stackNdx >= 0) {
-                stacks.get(stackNdx).handleAppCrashLocked(app);
-                stackNdx--;
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
+                stack.handleAppCrashLocked(app);
             }
         }
     }
@@ -3500,7 +3491,7 @@
         final ActivityStack stack = task.getStack();
 
         r.mLaunchTaskBehind = false;
-        mRecentTasks.addLocked(task);
+        mRecentTasks.add(task);
         mService.mTaskChangeNotificationController.notifyTaskStackChanged();
         r.setVisibility(false);
 
@@ -3522,10 +3513,9 @@
         try {
             // First the front stacks. In case any are not fullscreen and are in front of home.
             for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-                final int topStackNdx = stacks.size() - 1;
-                for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
-                    final ActivityStack stack = stacks.get(stackNdx);
+                final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+                for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                    final ActivityStack stack = display.getChildAt(stackNdx);
                     stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
                 }
             }
@@ -3536,10 +3526,9 @@
 
     void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            final int topStackNdx = stacks.size() - 1;
-            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 stack.addStartingWindowsForVisibleActivities(taskSwitch);
             }
         }
@@ -3555,20 +3544,20 @@
         }
         mTaskLayersChanged = false;
         for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
             int baseLayer = 0;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
+                baseLayer += stack.rankTaskLayers(baseLayer);
             }
         }
     }
 
     void clearOtherAppTimeTrackers(AppTimeTracker except) {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            final int topStackNdx = stacks.size() - 1;
-            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 stack.clearOtherAppTimeTrackers(except);
             }
         }
@@ -3576,10 +3565,9 @@
 
     void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            final int numStacks = stacks.size();
-            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 stack.scheduleDestroyActivities(app, reason);
             }
         }
@@ -3631,10 +3619,11 @@
         // let's iterate through the tasks and release the oldest one.
         final int numDisplays = mActivityDisplays.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            final int stackCount = display.getChildCount();
             // Step through all stacks starting from behind, to hit the oldest things first.
-            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            for (int stackNdx = 0; stackNdx < stackCount; stackNdx++) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 // Try to release activities in this stack; if we manage to, we are done.
                 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
                     return;
@@ -3646,14 +3635,14 @@
     boolean switchUserLocked(int userId, UserState uss) {
         final int focusStackId = mFocusedStack.getStackId();
         // We dismiss the docked stack whenever we switch users.
-        final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenStack();
+        final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack();
         if (dockedStack != null) {
             moveTasksToFullscreenStackLocked(dockedStack, mFocusedStack == dockedStack);
         }
         // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
         // also cause all tasks to be moved to the fullscreen stack at a position that is
         // appropriate.
-        removeStackLocked(PINNED_STACK_ID);
+        removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
 
         mUserStackInFront.put(mCurrentUser, focusStackId);
         final int restoreStackId = mUserStackInFront.get(userId, mHomeStack.mStackId);
@@ -3661,9 +3650,9 @@
 
         mStartingUsers.add(uss);
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 stack.switchUserLocked(userId);
                 TaskRecord task = stack.topTask();
                 if (task != null) {
@@ -3761,9 +3750,9 @@
 
     void validateTopActivitiesLocked() {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 final ActivityRecord r = stack.topRunningActivityLocked();
                 final ActivityState state = r == null ? DESTROYED : r.state;
                 if (isFocusedStack(stack)) {
@@ -3798,7 +3787,7 @@
         pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
         for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
             final ActivityDisplay display = mActivityDisplays.valueAt(i);
-            pw.println(prefix + "displayId=" + display.mDisplayId + " mStacks=" + display.mStacks);
+            display.dump(pw, prefix);
         }
         if (!mWaitingForActivityVisible.isEmpty()) {
             pw.print(prefix); pw.println("mWaitingForActivityVisible=");
@@ -3811,8 +3800,7 @@
         mService.mLockTaskController.dump(pw, prefix);
     }
 
-    public void writeToProto(ProtoOutputStream proto, long fieldId) {
-        final long token = proto.start(fieldId);
+    public void writeToProto(ProtoOutputStream proto) {
         super.writeToProto(proto, CONFIGURATION_CONTAINER);
         for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
             ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
@@ -3828,7 +3816,6 @@
         } else {
             proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
         }
-        proto.end(token);
     }
 
     /**
@@ -3857,9 +3844,9 @@
             ArrayList<ActivityRecord> activities = new ArrayList<>();
             int numDisplays = mActivityDisplays.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-                ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                    ActivityStack stack = stacks.get(stackNdx);
+                final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+                for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                    final ActivityStack stack = display.getChildAt(stackNdx);
                     if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
                         activities.addAll(stack.getDumpActivitiesLocked(name));
                     }
@@ -3892,11 +3879,13 @@
             ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
             pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
                     pw.println(" (activities from top to bottom):");
-            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
                 pw.println();
-                pw.println("  Stack #" + stack.mStackId + ":");
+                pw.println("  Stack #" + stack.mStackId
+                        + ": type=" + activityTypeToString(stack.getActivityType())
+                        + " mode=" + windowingModeToString(stack.getWindowingMode()));
                 pw.println("  mFullscreen=" + stack.mFullscreen);
                 pw.println("  isSleeping=" + stack.shouldSleepActivities());
                 pw.println("  mBounds=" + stack.mBounds);
@@ -4140,30 +4129,29 @@
         }
 
         synchronized (mService) {
-            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
-            if (activityDisplay != null) {
-                final boolean destroyContentOnRemoval
-                        = activityDisplay.shouldDestroyContentOnRemove();
-                final ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
-                while (!stacks.isEmpty()) {
-                    final ActivityStack stack = stacks.get(0);
-                    if (destroyContentOnRemoval) {
-                        moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY,
-                                false /* onTop */);
-                        stack.finishAllActivitiesLocked(true /* immediately */);
-                    } else {
-                        // Moving all tasks to fullscreen stack, because it's guaranteed to be
-                        // a valid launch stack for all activities. This way the task history from
-                        // external display will be preserved on primary after move.
-                        moveTasksToFullscreenStackLocked(stack, true /* onTop */);
-                    }
-                }
-
-                releaseSleepTokens(activityDisplay);
-
-                mActivityDisplays.remove(displayId);
-                mWindowManager.onDisplayRemoved(displayId);
+            final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
+            if (activityDisplay == null) {
+                return;
             }
+            final boolean destroyContentOnRemoval
+                    = activityDisplay.shouldDestroyContentOnRemove();
+            while (activityDisplay.getChildCount() > 0) {
+                final ActivityStack stack = activityDisplay.getChildAt(0);
+                if (destroyContentOnRemoval) {
+                    moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY, false /* onTop */);
+                    stack.finishAllActivitiesLocked(true /* immediately */);
+                } else {
+                    // Moving all tasks to fullscreen stack, because it's guaranteed to be
+                    // a valid launch stack for all activities. This way the task history from
+                    // external display will be preserved on primary after move.
+                    moveTasksToFullscreenStackLocked(stack, true /* onTop */);
+                }
+            }
+
+            releaseSleepTokens(activityDisplay);
+
+            mActivityDisplays.remove(displayId);
+            mWindowManager.onDisplayRemoved(displayId);
         }
     }
 
@@ -4235,7 +4223,7 @@
         info.userId = stack.mCurrentUser;
         info.visible = stack.shouldBeVisible(null);
         // A stack might be not attached to a display.
-        info.position = display != null ? display.mStacks.indexOf(stack) : 0;
+        info.position = display != null ? display.getIndexOf(stack) : 0;
         info.configuration.setTo(stack.getConfiguration());
 
         ArrayList<TaskRecord> tasks = stack.getAllTasks();
@@ -4281,25 +4269,25 @@
     ArrayList<StackInfo> getAllStackInfosLocked() {
         ArrayList<StackInfo> list = new ArrayList<>();
         for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
-            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
-                list.add(getStackInfo(stacks.get(ndx)));
+            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getChildAt(stackNdx);
+                list.add(getStackInfo(stack));
             }
         }
         return list;
     }
 
     void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredWindowingMode,
-            int preferredDisplayId, int actualStackId) {
+            int preferredDisplayId, ActivityStack actualStack) {
         handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredDisplayId,
-                actualStackId, false /* forceNonResizable */);
+                actualStack, false /* forceNonResizable */);
     }
 
     void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredWindowingMode,
-            int preferredDisplayId, int actualStackId, boolean forceNonResizable) {
+            int preferredDisplayId, ActivityStack actualStack, boolean forceNonResizable) {
         final boolean isSecondaryDisplayPreferred =
                 (preferredDisplayId != DEFAULT_DISPLAY && preferredDisplayId != INVALID_DISPLAY);
-        final ActivityStack actualStack = getStack(actualStackId);
         final boolean inSplitScreenMode = actualStack != null
                 && actualStack.inSplitScreenWindowingMode();
         if (((!inSplitScreenMode && preferredWindowingMode != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
@@ -4315,8 +4303,8 @@
                 // The task landed on an inappropriate display somehow, move it to the default
                 // display.
                 // TODO(multi-display): Find proper stack for the task on the default display.
-                mService.moveTaskToStack(task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
-                        true /* toTop */);
+                mService.setTaskWindowingMode(task.taskId,
+                        WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */);
                 launchOnSecondaryDisplayFailed = true;
             } else {
                 // The task might have landed on a display different from requested.
@@ -4346,10 +4334,9 @@
             // Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
             // we need to move it to top of fullscreen stack, otherwise it will be covered.
 
-            final ActivityStack dockedStack = task.getStack().getDisplay().getSplitScreenStack();
+            final ActivityStack dockedStack = task.getStack().getDisplay().getSplitScreenPrimaryStack();
             if (dockedStack != null) {
-                moveTasksToFullscreenStackLocked(dockedStack,
-                        actualStackId == dockedStack.getStackId());
+                moveTasksToFullscreenStackLocked(dockedStack, actualStack == dockedStack);
             }
         } else if (topActivity != null && topActivity.isNonResizableOrForcedResizable()
                 && !topActivity.noDisplay) {
@@ -4402,7 +4389,7 @@
     void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, ActivityStack prevStack) {
         final ActivityStack stack = task.getStack();
         if (prevStack == null || prevStack == stack
-                || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
+                || (!prevStack.inPinnedWindowingMode() && !stack.inPinnedWindowingMode())) {
             return;
         }
 
@@ -4561,14 +4548,13 @@
         if (display == null) {
             return null;
         }
-        final ArrayList<ActivityStack> stacks = display.mStacks;
-        for (int i = stacks.size() - 1; i >= 0; i--) {
-            if (stacks.get(i) == stack && i > 0) {
-                return stacks.get(i - 1);
+        for (int i = display.getChildCount() - 1; i >= 0; i--) {
+            if (display.getChildAt(i) == stack && i > 0) {
+                return display.getChildAt(i - 1);
             }
         }
         throw new IllegalStateException("Failed to find a stack behind stack=" + stack
-                + " in=" + stacks);
+                + " in=" + display);
     }
 
     /**
@@ -4681,8 +4667,8 @@
         for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
             final ActivityDisplay display = mActivityDisplays.valueAt(i);
             // Traverse all stacks on a display.
-            for (int j = display.mStacks.size() - 1; j >= 0; j--) {
-                final ActivityStack stack = display.mStacks.get(j);
+            for (int j = display.getChildCount() - 1; j >= 0; --j) {
+                final ActivityStack stack = display.getChildAt(j);
                 // Get top activity from a visible stack and add it to the list.
                 if (stack.shouldBeVisible(null /* starting */)) {
                     final ActivityRecord top = stack.topActivity();
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index d444c66..6f74d85 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -26,15 +26,9 @@
 import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
 import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
-import static android.app.ActivityManager.StackId;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.app.ActivityManager.StackId.isDynamicStack;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
@@ -121,7 +115,6 @@
 import com.android.internal.app.IVoiceInteractor;
 import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
 import com.android.server.pm.InstantAppResolver;
-import com.android.server.wm.WindowManagerService;
 
 import java.io.PrintWriter;
 import java.text.DateFormat;
@@ -140,11 +133,11 @@
     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
     private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
+    private static final int INVALID_LAUNCH_MODE = -1;
 
     private final ActivityManagerService mService;
     private final ActivityStackSupervisor mSupervisor;
     private final ActivityStartInterceptor mInterceptor;
-    private WindowManagerService mWindowManager;
 
     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches = new ArrayList<>();
 
@@ -154,9 +147,7 @@
     private int mCallingUid;
     private ActivityOptions mOptions;
 
-    private boolean mLaunchSingleTop;
-    private boolean mLaunchSingleInstance;
-    private boolean mLaunchSingleTask;
+    private int mLaunchMode;
     private boolean mLaunchTaskBehind;
     private int mLaunchFlags;
 
@@ -166,6 +157,7 @@
     private boolean mDoResume;
     private int mStartFlags;
     private ActivityRecord mSourceRecord;
+
     // The display to launch the activity onto, barring any strong reason to do otherwise.
     private int mPreferredDisplayId;
 
@@ -195,8 +187,6 @@
     private IVoiceInteractionSession mVoiceSession;
     private IVoiceInteractor mVoiceInteractor;
 
-    private boolean mUsingVr2dDisplay;
-
     // Last home activity record we attempted to start
     private final ActivityRecord[] mLastHomeActivityStartRecord = new ActivityRecord[1];
     // The result of the last home activity we attempted to start.
@@ -216,11 +206,9 @@
         mCallingUid = -1;
         mOptions = null;
 
-        mLaunchSingleTop = false;
-        mLaunchSingleInstance = false;
-        mLaunchSingleTask = false;
         mLaunchTaskBehind = false;
         mLaunchFlags = 0;
+        mLaunchMode = INVALID_LAUNCH_MODE;
 
         mLaunchBounds = null;
 
@@ -248,16 +236,13 @@
         mVoiceSession = null;
         mVoiceInteractor = null;
 
-        mUsingVr2dDisplay = false;
-
         mIntentDelivered = false;
     }
 
-    ActivityStarter(ActivityManagerService service, ActivityStackSupervisor supervisor) {
+    ActivityStarter(ActivityManagerService service) {
         mService = service;
-        mSupervisor = supervisor;
+        mSupervisor = mService.mStackSupervisor;
         mInterceptor = new ActivityStartInterceptor(mService, mSupervisor);
-        mUsingVr2dDisplay = false;
     }
 
     int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
@@ -610,38 +595,41 @@
             mSupervisor.reportTaskToFrontNoLaunch(mStartActivity);
         }
 
-        int startedActivityStackId = INVALID_STACK_ID;
+        ActivityStack startedActivityStack = null;
         final ActivityStack currentStack = r.getStack();
         if (currentStack != null) {
-            startedActivityStackId = currentStack.mStackId;
+            startedActivityStack = currentStack;
         } else if (mTargetStack != null) {
-            startedActivityStackId = targetStack.mStackId;
+            startedActivityStack = targetStack;
         }
 
-        if (startedActivityStackId == DOCKED_STACK_ID) {
-            final ActivityStack homeStack = mSupervisor.getDefaultDisplay().getStack(
-                            WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
+        if (startedActivityStack == null) {
+            return;
+        }
+
+        if (startedActivityStack.inSplitScreenPrimaryWindowingMode()) {
+            final ActivityStack homeStack = mSupervisor.mHomeStack;
             final boolean homeStackVisible = homeStack != null && homeStack.isVisible();
             if (homeStackVisible) {
                 // We launch an activity while being in home stack, which means either launcher or
                 // recents into docked stack. We don't want the launched activity to be alone in a
                 // docked stack, so we want to immediately launch recents too.
                 if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch.");
-                mWindowManager.showRecentApps(true /* fromHome */);
+                mService.mWindowManager.showRecentApps(true /* fromHome */);
             }
             return;
         }
 
         boolean clearedTask = (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK) && (mReuseTask != null);
-        if (startedActivityStackId == PINNED_STACK_ID && (result == START_TASK_TO_FRONT
-                || result == START_DELIVERED_TO_TOP || clearedTask)) {
+        if (startedActivityStack.inPinnedWindowingMode()
+                && (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP
+                || clearedTask)) {
             // The activity was already running in the pinned stack so it wasn't started, but either
             // brought to the front or the new intent was delivered to it since it was already in
             // front. Notify anyone interested in this piece of information.
             mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt(
                     clearedTask);
-            return;
         }
     }
 
@@ -1062,7 +1050,7 @@
             // operations.
             if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                     || isDocumentLaunchesIntoExisting(mLaunchFlags)
-                    || mLaunchSingleInstance || mLaunchSingleTask) {
+                    || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
                 final TaskRecord task = reusedActivity.getTask();
 
                 // In this situation we want to remove all activities from the task up to the one
@@ -1145,7 +1133,7 @@
                 && top.userId == mStartActivity.userId
                 && top.app != null && top.app.thread != null
                 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
-                || mLaunchSingleTop || mLaunchSingleTask);
+                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
         if (dontStart) {
             // For paranoia, make sure we have correctly resumed the top activity.
             topStack.mLastPausedActivity = null;
@@ -1164,7 +1152,7 @@
             // Don't use mStartActivity.task to show the toast. We're not starting a new activity
             // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
             mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
-                    preferredLaunchDisplayId, topStack.mStackId);
+                    preferredLaunchDisplayId, topStack);
 
             return START_DELIVERED_TO_TOP;
         }
@@ -1227,7 +1215,7 @@
                 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                 // Go ahead and tell window manager to execute app transition for this activity
                 // since the app transition will not be triggered through the resume channel.
-                mWindowManager.executeAppTransition();
+                mService.mWindowManager.executeAppTransition();
             } else {
                 // If the target stack was not previously focusable (previous top running activity
                 // on that stack was not visible) then any prior calls to move the stack to the
@@ -1240,13 +1228,13 @@
                 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                         mOptions);
             }
-        } else {
-            mSupervisor.addRecentActivity(mStartActivity);
+        } else if (mStartActivity != null) {
+            mSupervisor.mRecentTasks.add(mStartActivity.getTask());
         }
         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
 
         mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
-                preferredLaunchDisplayId, mTargetStack.mStackId);
+                preferredLaunchDisplayId, mTargetStack);
 
         return START_SUCCESS;
     }
@@ -1268,13 +1256,13 @@
 
         mLaunchBounds = getOverrideBounds(r, options, inTask);
 
-        mLaunchSingleTop = r.launchMode == LAUNCH_SINGLE_TOP;
-        mLaunchSingleInstance = r.launchMode == LAUNCH_SINGLE_INSTANCE;
-        mLaunchSingleTask = r.launchMode == LAUNCH_SINGLE_TASK;
+        mLaunchMode = r.launchMode;
+
         mLaunchFlags = adjustLaunchFlagsToDocumentMode(
-                r, mLaunchSingleInstance, mLaunchSingleTask, mIntent.getFlags());
+                r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
+                LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
         mLaunchTaskBehind = r.mLaunchTaskBehind
-                && !mLaunchSingleTask && !mLaunchSingleInstance
+                && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
 
         sendNewTaskResultRequestIfNeeded();
@@ -1384,7 +1372,7 @@
 
             // If this task is empty, then we are adding the first activity -- it
             // determines the root, and must be launching as a NEW_TASK.
-            if (mLaunchSingleInstance || mLaunchSingleTask) {
+            if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
                 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
                     ActivityOptions.abort(mOptions);
                     throw new IllegalArgumentException("Trying to launch singleInstance/Task "
@@ -1427,7 +1415,7 @@
             // in any task/stack, however it could launch other activities like ResolverActivity,
             // and we want those to stay in the original task.
             if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
-                    && mSourceRecord.isFreeform())  {
+                    && mSourceRecord.inFreeformWindowingMode())  {
                 mAddingToTask = true;
             }
         }
@@ -1446,7 +1434,7 @@
                 // instance...  this new activity it is starting must go on its
                 // own task.
                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
-            } else if (mLaunchSingleInstance || mLaunchSingleTask) {
+            } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
                 // The activity being started is a single instance...  it always
                 // gets launched into its own task.
                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
@@ -1497,7 +1485,7 @@
         // launch this as a new task behind the current one.
         boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
                 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
-                || mLaunchSingleInstance || mLaunchSingleTask;
+                || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
         // If bring to front is requested, and no result is requested and we have not been given
         // an explicit task to launch in to, and we can find a task that was started with this
         // same component, then instead of launching bring that one to the front.
@@ -1507,7 +1495,7 @@
             final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
             intentActivity = task != null ? task.getTopActivity() : null;
         } else if (putIntoExistingTask) {
-            if (mLaunchSingleInstance) {
+            if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
                 // There can be one and only one instance of single instance activity in the
                 // history, and it is always in its own unique task, so we do a special search.
                intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
@@ -1516,7 +1504,7 @@
                 // For the launch adjacent case we only want to put the activity in an existing
                 // task if the activity already exists in the history.
                 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
-                        !mLaunchSingleTask);
+                        !(LAUNCH_SINGLE_TASK == mLaunchMode));
             } else {
                 // Otherwise find the best task to put the activity in.
                 intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId);
@@ -1545,7 +1533,6 @@
             if (DEBUG_STACK) {
                 Slog.d(TAG, "getSourceDisplayId :" + displayId);
             }
-            mUsingVr2dDisplay = true;
             return displayId;
         }
 
@@ -1667,7 +1654,7 @@
         }
 
         mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(),
-                WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack.mStackId);
+                WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
 
         // If the caller has requested that the target task be reset, then do so.
         if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
@@ -1719,7 +1706,7 @@
             // mTaskToReturnTo values and we don't want to overwrite them accidentally.
             mMovedOtherTask = true;
         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
-                || mLaunchSingleInstance || mLaunchSingleTask) {
+                || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
             ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
                     mLaunchFlags);
             if (top == null) {
@@ -1748,7 +1735,8 @@
             // so we take that as a request to bring the task to the foreground. If the top
             // activity in the task is the root activity, deliver this new intent to it if it
             // desires.
-            if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop)
+            if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
+                        || LAUNCH_SINGLE_TOP == mLaunchMode)
                     && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
                 if (intentActivity.frontOfTask) {
                     intentActivity.getTask().setIntent(mStartActivity);
@@ -1952,7 +1940,7 @@
         if (top != null && top.realActivity.equals(mStartActivity.realActivity)
                 && top.userId == mStartActivity.userId) {
             if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
-                    || mLaunchSingleTop || mLaunchSingleTask) {
+                    || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
                 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
                         mStartActivity.appTimeTracker, "inTaskToFront");
                 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
@@ -2001,9 +1989,9 @@
             return;
         }
 
-        final int stackId = task.getStackId();
-        if (StackId.resizeStackWithLaunchBounds(stackId)) {
-            mService.resizeStack(stackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
+        final ActivityStack stack = task.getStack();
+        if (stack != null && stack.resizeStackWithLaunchBounds()) {
+            mService.resizeStack(stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
         } else {
             task.updateOverrideConfiguration(bounds);
         }
@@ -2115,11 +2103,10 @@
         }
         if (stack == null) {
             // We first try to put the task in the first dynamic stack on home display.
-            final ArrayList<ActivityStack> homeDisplayStacks =
-                    mSupervisor.getStacksOnDefaultDisplay();
-            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                stack = homeDisplayStacks.get(stackNdx);
-                if (isDynamicStack(stack.mStackId)) {
+            final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                stack = display.getChildAt(stackNdx);
+                if (!stack.isOnHomeDisplay()) {
                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
                             "computeStackFocus: Setting focused stack=" + stack);
                     return stack;
@@ -2138,7 +2125,6 @@
     private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
         final ActivityStack focusedStack = mSupervisor.mFocusedStack;
         final boolean canUseFocusedStack;
-        final int focusedStackId = mSupervisor.mFocusedStack.mStackId;
         if (focusedStack.isActivityTypeAssistant()) {
             canUseFocusedStack = r.isActivityTypeAssistant();
         } else {
@@ -2161,7 +2147,7 @@
                 default:
                     // Dynamic stacks behave similarly to the fullscreen stack and can contain any
                     // resizeable task.
-                    canUseFocusedStack = isDynamicStack(focusedStackId)
+                    canUseFocusedStack = !focusedStack.isOnHomeDisplay()
                             && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
             }
         }
@@ -2177,7 +2163,8 @@
             return mReuseTask.getStack();
         }
 
-        final int vrDisplayId = mUsingVr2dDisplay ? mPreferredDisplayId : INVALID_DISPLAY;
+        final int vrDisplayId = mPreferredDisplayId == mService.mVr2dDisplayId
+                ? mPreferredDisplayId : INVALID_DISPLAY;
         final ActivityStack launchStack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP,
                 vrDisplayId);
 
@@ -2205,7 +2192,7 @@
                 return mSupervisor.mFocusedStack;
             }
 
-            if (parentStack != null && parentStack.isDockedStack()) {
+            if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
                 // If parent was in docked stack, the natural place to launch another activity
                 // will be fullscreen, so it can appear alongside the docked window.
                 final int activityType = mSupervisor.resolveActivityType(r, mOptions, task);
@@ -2215,8 +2202,8 @@
                 // If the parent is not in the docked stack, we check if there is docked window
                 // and if yes, we will launch into that stack. If not, we just put the new
                 // activity into parent's stack, because we can't find a better place.
-                final ActivityStack dockedStack = mSupervisor.getDefaultDisplay().getStack(
-                                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
+                final ActivityStack dockedStack =
+                        mSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
                 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
                     // There is a docked stack, but it isn't visible, so we can't launch into that.
                     return null;
@@ -2236,8 +2223,8 @@
         return newBounds;
     }
 
-    void setWindowManager(WindowManagerService wm) {
-        mWindowManager = wm;
+    private boolean isLaunchModeOneOf(int mode1, int mode2) {
+        return mode1 == mLaunchMode || mode2 == mLaunchMode;
     }
 
     static boolean isDocumentLaunchesIntoExisting(int flags) {
@@ -2318,11 +2305,11 @@
         }
         pw.print(prefix);
         pw.print("mLaunchSingleTop=");
-        pw.print(mLaunchSingleTop);
+        pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
         pw.print(" mLaunchSingleInstance=");
-        pw.print(mLaunchSingleInstance);
+        pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
         pw.print(" mLaunchSingleTask=");
-        pw.println(mLaunchSingleTask);
+        pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
         pw.print(prefix);
         pw.print("mLaunchFlags=0x");
         pw.print(Integer.toHexString(mLaunchFlags));
diff --git a/services/core/java/com/android/server/am/AppTaskImpl.java b/services/core/java/com/android/server/am/AppTaskImpl.java
new file mode 100644
index 0000000..a4e2e70
--- /dev/null
+++ b/services/core/java/com/android/server/am/AppTaskImpl.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2017 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.server.am;
+
+import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
+
+import android.app.ActivityManager;
+import android.app.IAppTask;
+import android.app.IApplicationThread;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.UserHandle;
+
+/**
+ * An implementation of IAppTask, that allows an app to manage its own tasks via
+ * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
+ * only the process that calls getAppTasks() can call the AppTask methods.
+ */
+class AppTaskImpl extends IAppTask.Stub {
+    private ActivityManagerService mService;
+
+    private int mTaskId;
+    private int mCallingUid;
+
+    public AppTaskImpl(ActivityManagerService service, int taskId, int callingUid) {
+        mService = service;
+        mTaskId = taskId;
+        mCallingUid = callingUid;
+    }
+
+    private void checkCaller() {
+        if (mCallingUid != Binder.getCallingUid()) {
+            throw new SecurityException("Caller " + mCallingUid
+                    + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
+        }
+    }
+
+    @Override
+    public void finishAndRemoveTask() {
+        checkCaller();
+
+        synchronized (mService) {
+            long origId = Binder.clearCallingIdentity();
+            try {
+                // We remove the task from recents to preserve backwards
+                if (!mService.mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
+                        REMOVE_FROM_RECENTS)) {
+                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+    }
+
+    @Override
+    public ActivityManager.RecentTaskInfo getTaskInfo() {
+        checkCaller();
+
+        synchronized (mService) {
+            long origId = Binder.clearCallingIdentity();
+            try {
+                TaskRecord tr = mService.mStackSupervisor.anyTaskForIdLocked(mTaskId);
+                if (tr == null) {
+                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
+                }
+                return RecentTasks.createRecentTaskInfo(tr);
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+    }
+
+    @Override
+    public void moveToFront() {
+        checkCaller();
+        // Will bring task to front if it already has a root activity.
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                mService.mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public int startActivity(IBinder whoThread, String callingPackage,
+            Intent intent, String resolvedType, Bundle bOptions) {
+        checkCaller();
+
+        int callingUser = UserHandle.getCallingUserId();
+        TaskRecord tr;
+        IApplicationThread appThread;
+        synchronized (mService) {
+            tr = mService.mStackSupervisor.anyTaskForIdLocked(mTaskId);
+            if (tr == null) {
+                throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
+            }
+            appThread = IApplicationThread.Stub.asInterface(whoThread);
+            if (appThread == null) {
+                throw new IllegalArgumentException("Bad app thread " + appThread);
+            }
+        }
+        return mService.mActivityStarter.startActivityMayWait(appThread, -1, callingPackage,
+                intent, resolvedType, null, null, null, null, 0, 0, null, null,
+                null, bOptions, false, callingUser, tr, "AppTaskImpl");
+    }
+
+    @Override
+    public void setExcludeFromRecents(boolean exclude) {
+        checkCaller();
+
+        synchronized (mService) {
+            long origId = Binder.clearCallingIdentity();
+            try {
+                TaskRecord tr = mService.mStackSupervisor.anyTaskForIdLocked(mTaskId);
+                if (tr == null) {
+                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
+                }
+                Intent intent = tr.getBaseIntent();
+                if (exclude) {
+                    intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                } else {
+                    intent.setFlags(intent.getFlags()
+                            & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java
index f96b06f..7ff227f 100644
--- a/services/core/java/com/android/server/am/BroadcastFilter.java
+++ b/services/core/java/com/android/server/am/BroadcastFilter.java
@@ -19,6 +19,9 @@
 import android.content.IntentFilter;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.server.am.proto.BroadcastFilterProto;
 
 import java.io.PrintWriter;
 
@@ -44,27 +47,38 @@
         instantApp = _instantApp;
         visibleToInstantApp = _visibleToInstantApp;
     }
-    
+
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+        long token = proto.start(fieldId);
+        super.writeToProto(proto, BroadcastFilterProto.INTENT_FILTER);
+        if (requiredPermission != null) {
+            proto.write(BroadcastFilterProto.REQUIRED_PERMISSION, requiredPermission);
+        }
+        proto.write(BroadcastFilterProto.HEX_HASH, Integer.toHexString(System.identityHashCode(this)));
+        proto.write(BroadcastFilterProto.OWNING_USER_ID, owningUserId);
+        proto.end(token);
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         dumpInReceiverList(pw, new PrintWriterPrinter(pw), prefix);
         receiverList.dumpLocal(pw, prefix);
     }
-    
+
     public void dumpBrief(PrintWriter pw, String prefix) {
         dumpBroadcastFilterState(pw, prefix);
     }
-    
+
     public void dumpInReceiverList(PrintWriter pw, Printer pr, String prefix) {
         super.dump(pr, prefix);
         dumpBroadcastFilterState(pw, prefix);
     }
-    
+
     void dumpBroadcastFilterState(PrintWriter pw, String prefix) {
         if (requiredPermission != null) {
             pw.print(prefix); pw.print("requiredPermission="); pw.println(requiredPermission);
         }
     }
-    
+
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("BroadcastFilter{");
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index d835454..c62cc38 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -51,9 +51,12 @@
 import android.util.EventLog;
 import android.util.Slog;
 import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
 
 import static com.android.server.am.ActivityManagerDebugConfig.*;
 
+import com.android.server.am.proto.BroadcastQueueProto;
+
 /**
  * BROADCASTS
  *
@@ -1585,6 +1588,55 @@
                 && (mPendingBroadcast == null);
     }
 
+    void writeToProto(ProtoOutputStream proto, long fieldId) {
+        long token = proto.start(fieldId);
+        proto.write(BroadcastQueueProto.QUEUE_NAME, mQueueName);
+        int N;
+        N = mParallelBroadcasts.size();
+        for (int i = N - 1; i >= 0; i--) {
+            mParallelBroadcasts.get(i).writeToProto(proto, BroadcastQueueProto.PARALLEL_BROADCASTS);
+        }
+        N = mOrderedBroadcasts.size();
+        for (int i = N - 1; i >= 0; i--) {
+            mOrderedBroadcasts.get(i).writeToProto(proto, BroadcastQueueProto.ORDERED_BROADCASTS);
+        }
+        if (mPendingBroadcast != null) {
+            mPendingBroadcast.writeToProto(proto, BroadcastQueueProto.PENDING_BROADCAST);
+        }
+
+        int lastIndex = mHistoryNext;
+        int ringIndex = lastIndex;
+        do {
+            // increasing index = more recent entry, and we want to print the most
+            // recent first and work backwards, so we roll through the ring backwards.
+            ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_HISTORY);
+            BroadcastRecord r = mBroadcastHistory[ringIndex];
+            if (r != null) {
+                r.writeToProto(proto, BroadcastQueueProto.HISTORICAL_BROADCASTS);
+            }
+        } while (ringIndex != lastIndex);
+
+        lastIndex = ringIndex = mSummaryHistoryNext;
+        do {
+            ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_SUMMARY_HISTORY);
+            Intent intent = mBroadcastSummaryHistory[ringIndex];
+            if (intent == null) {
+                continue;
+            }
+            long summaryToken = proto.start(BroadcastQueueProto.HISTORICAL_BROADCASTS_SUMMARY);
+            intent.writeToProto(proto, BroadcastQueueProto.BroadcastSummary.INTENT,
+                    false, true, true, false);
+            proto.write(BroadcastQueueProto.BroadcastSummary.ENQUEUE_CLOCK_TIME_MS,
+                    mSummaryHistoryEnqueueTime[ringIndex]);
+            proto.write(BroadcastQueueProto.BroadcastSummary.DISPATCH_CLOCK_TIME_MS,
+                    mSummaryHistoryDispatchTime[ringIndex]);
+            proto.write(BroadcastQueueProto.BroadcastSummary.FINISH_CLOCK_TIME_MS,
+                    mSummaryHistoryFinishTime[ringIndex]);
+            proto.end(summaryToken);
+        } while (ringIndex != lastIndex);
+        proto.end(token);
+    }
+
     final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 6bc0744..5b3b2a8 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -30,6 +30,9 @@
 import android.os.UserHandle;
 import android.util.PrintWriterPrinter;
 import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.server.am.proto.BroadcastRecordProto;
 
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
@@ -331,9 +334,17 @@
         return didSomething;
     }
 
+    @Override
     public String toString() {
         return "BroadcastRecord{"
             + Integer.toHexString(System.identityHashCode(this))
             + " u" + userId + " " + intent.getAction() + "}";
     }
+
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+        long token = proto.start(fieldId);
+        proto.write(BroadcastRecordProto.USER_ID, userId);
+        proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction());
+        proto.end(token);
+    }
 }
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 5c48f90..c3fed17 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -16,7 +16,6 @@
 
 package com.android.server.am;
 
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
@@ -47,7 +46,6 @@
 import com.android.server.wm.WindowManagerService;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 /**
  * Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are
@@ -238,9 +236,9 @@
         final ActivityRecord lastDismissingKeyguardActivity = mDismissingKeyguardActivity;
         mOccluded = false;
         mDismissingKeyguardActivity = null;
-        final ArrayList<ActivityStack> stacks = mStackSupervisor.getStacksOnDefaultDisplay();
-        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final ActivityStack stack = stacks.get(stackNdx);
+        final ActivityDisplay display = mStackSupervisor.getDefaultDisplay();
+        for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = display.getChildAt(stackNdx);
 
             // Only the focused stack top activity may control occluded state
             if (mStackSupervisor.isFocusedStack(stack)) {
@@ -342,7 +340,7 @@
             // show on top of the lock screen. In this can we want to dismiss the docked
             // stack since it will be complicated/risky to try to put the activity on top
             // of the lock screen in the right fullscreen configuration.
-            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getSplitScreenStack();
+            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
             if (stack == null) {
                 return;
             }
diff --git a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
index d652341..0dc73e9 100644
--- a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
+++ b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
@@ -24,8 +24,8 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.Slog;
-import android.view.Display;
 import android.view.Gravity;
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
 
@@ -64,43 +64,11 @@
     private static final int SHIFT_POLICY_HORIZONTAL_RIGHT = 2;
     private static final int SHIFT_POLICY_HORIZONTAL_LEFT = 3;
 
-    private boolean mDefaultStartBoundsConfigurationSet = false;
     private final Rect mAvailableRect = new Rect();
     private final Rect mTmpProposal = new Rect();
     private final Rect mTmpOriginal = new Rect();
 
-    private int mDefaultFreeformStartX;
-    private int mDefaultFreeformStartY;
-    private int mDefaultFreeformWidth;
-    private int mDefaultFreeformHeight;
-    private int mDefaultFreeformStepHorizontal;
-    private int mDefaultFreeformStepVertical;
-    private int mDisplayWidth;
-    private int mDisplayHeight;
-
-    void setDisplay(Display display) {
-        Point size = new Point();
-        display.getSize(size);
-        mDisplayWidth = size.x;
-        mDisplayHeight = size.y;
-    }
-
-    void configure(Rect stackBounds) {
-        if (stackBounds == null) {
-            mAvailableRect.set(0, 0, mDisplayWidth, mDisplayHeight);
-        } else {
-            mAvailableRect.set(stackBounds);
-        }
-        int width = mAvailableRect.width();
-        int height = mAvailableRect.height();
-        mDefaultFreeformStartX = mAvailableRect.left + width / MARGIN_SIZE_DENOMINATOR;
-        mDefaultFreeformStartY = mAvailableRect.top + height / MARGIN_SIZE_DENOMINATOR;
-        mDefaultFreeformWidth = width / WINDOW_SIZE_DENOMINATOR;
-        mDefaultFreeformHeight = height / WINDOW_SIZE_DENOMINATOR;
-        mDefaultFreeformStepHorizontal = Math.max(width / STEP_DENOMINATOR, MINIMAL_STEP);
-        mDefaultFreeformStepVertical = Math.max(height / STEP_DENOMINATOR, MINIMAL_STEP);
-        mDefaultStartBoundsConfigurationSet = true;
-    }
+    private final Point mDisplaySize = new Point();
 
     /**
      * Tries to set task's bound in a way that it won't collide with any other task. By colliding
@@ -114,104 +82,154 @@
      */
     void updateDefaultBounds(TaskRecord task, ArrayList<TaskRecord> tasks,
             @Nullable ActivityInfo.WindowLayout windowLayout) {
-        if (!mDefaultStartBoundsConfigurationSet) {
-            return;
-        }
+        updateAvailableRect(task, mAvailableRect);
+
         if (windowLayout == null) {
-            positionCenter(task, tasks, mDefaultFreeformWidth, mDefaultFreeformHeight);
+            positionCenter(task, tasks, mAvailableRect, getFreeformWidth(mAvailableRect),
+                    getFreeformHeight(mAvailableRect));
             return;
         }
-        int width = getFinalWidth(windowLayout);
-        int height = getFinalHeight(windowLayout);
+        int width = getFinalWidth(windowLayout, mAvailableRect);
+        int height = getFinalHeight(windowLayout, mAvailableRect);
         int verticalGravity = windowLayout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
         int horizontalGravity = windowLayout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
         if (verticalGravity == Gravity.TOP) {
             if (horizontalGravity == Gravity.RIGHT) {
-                positionTopRight(task, tasks, width, height);
+                positionTopRight(task, tasks, mAvailableRect, width, height);
             } else {
-                positionTopLeft(task, tasks, width, height);
+                positionTopLeft(task, tasks, mAvailableRect, width, height);
             }
         } else if (verticalGravity == Gravity.BOTTOM) {
             if (horizontalGravity == Gravity.RIGHT) {
-                positionBottomRight(task, tasks, width, height);
+                positionBottomRight(task, tasks, mAvailableRect, width, height);
             } else {
-                positionBottomLeft(task, tasks, width, height);
+                positionBottomLeft(task, tasks, mAvailableRect, width, height);
             }
         } else {
             // Some fancy gravity setting that we don't support yet. We just put the activity in the
             // center.
             Slog.w(TAG, "Received unsupported gravity: " + windowLayout.gravity
                     + ", positioning in the center instead.");
-            positionCenter(task, tasks, width, height);
+            positionCenter(task, tasks, mAvailableRect, width, height);
         }
     }
 
-    private int getFinalWidth(ActivityInfo.WindowLayout windowLayout) {
-        int width = mDefaultFreeformWidth;
+    private void updateAvailableRect(TaskRecord task, Rect availableRect) {
+        final Rect stackBounds = task.getStack().mBounds;
+
+        if (stackBounds != null) {
+            availableRect.set(stackBounds);
+        } else {
+            task.getStack().getDisplay().mDisplay.getSize(mDisplaySize);
+            availableRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
+        }
+    }
+
+    @VisibleForTesting
+    static int getFreeformStartLeft(Rect bounds) {
+        return bounds.left + bounds.width() / MARGIN_SIZE_DENOMINATOR;
+    }
+
+    @VisibleForTesting
+    static int getFreeformStartTop(Rect bounds) {
+        return bounds.top + bounds.height() / MARGIN_SIZE_DENOMINATOR;
+    }
+
+    @VisibleForTesting
+    static int getFreeformWidth(Rect bounds) {
+        return bounds.width() / WINDOW_SIZE_DENOMINATOR;
+    }
+
+    @VisibleForTesting
+    static int getFreeformHeight(Rect bounds) {
+        return bounds.height() / WINDOW_SIZE_DENOMINATOR;
+    }
+
+    @VisibleForTesting
+    static int getHorizontalStep(Rect bounds) {
+        return Math.max(bounds.width() / STEP_DENOMINATOR, MINIMAL_STEP);
+    }
+
+    @VisibleForTesting
+    static int getVerticalStep(Rect bounds) {
+        return Math.max(bounds.height() / STEP_DENOMINATOR, MINIMAL_STEP);
+    }
+
+
+
+    private int getFinalWidth(ActivityInfo.WindowLayout windowLayout, Rect availableRect) {
+        int width = getFreeformWidth(availableRect);
         if (windowLayout.width > 0) {
             width = windowLayout.width;
         }
         if (windowLayout.widthFraction > 0) {
-            width = (int) (mAvailableRect.width() * windowLayout.widthFraction);
+            width = (int) (availableRect.width() * windowLayout.widthFraction);
         }
         return width;
     }
 
-    private int getFinalHeight(ActivityInfo.WindowLayout windowLayout) {
-        int height = mDefaultFreeformHeight;
+    private int getFinalHeight(ActivityInfo.WindowLayout windowLayout, Rect availableRect) {
+        int height = getFreeformHeight(availableRect);
         if (windowLayout.height > 0) {
             height = windowLayout.height;
         }
         if (windowLayout.heightFraction > 0) {
-            height = (int) (mAvailableRect.height() * windowLayout.heightFraction);
+            height = (int) (availableRect.height() * windowLayout.heightFraction);
         }
         return height;
     }
 
-    private void positionBottomLeft(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
-            int height) {
-        mTmpProposal.set(mAvailableRect.left, mAvailableRect.bottom - height,
-                mAvailableRect.left + width, mAvailableRect.bottom);
-        position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_RIGHT);
+    private void positionBottomLeft(TaskRecord task, ArrayList<TaskRecord> tasks,
+            Rect availableRect, int width, int height) {
+        mTmpProposal.set(availableRect.left, availableRect.bottom - height,
+                availableRect.left + width, availableRect.bottom);
+        position(task, tasks, availableRect, mTmpProposal, !ALLOW_RESTART,
+                SHIFT_POLICY_HORIZONTAL_RIGHT);
     }
 
-    private void positionBottomRight(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
-            int height) {
-        mTmpProposal.set(mAvailableRect.right - width, mAvailableRect.bottom - height,
-                mAvailableRect.right, mAvailableRect.bottom);
-        position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_LEFT);
+    private void positionBottomRight(TaskRecord task, ArrayList<TaskRecord> tasks,
+            Rect availableRect, int width, int height) {
+        mTmpProposal.set(availableRect.right - width, availableRect.bottom - height,
+                availableRect.right, availableRect.bottom);
+        position(task, tasks, availableRect, mTmpProposal, !ALLOW_RESTART,
+                SHIFT_POLICY_HORIZONTAL_LEFT);
     }
 
-    private void positionTopLeft(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
-            int height) {
-        mTmpProposal.set(mAvailableRect.left, mAvailableRect.top,
-                mAvailableRect.left + width, mAvailableRect.top + height);
-        position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_RIGHT);
+    private void positionTopLeft(TaskRecord task, ArrayList<TaskRecord> tasks,
+            Rect availableRect, int width, int height) {
+        mTmpProposal.set(availableRect.left, availableRect.top,
+                availableRect.left + width, availableRect.top + height);
+        position(task, tasks, availableRect, mTmpProposal, !ALLOW_RESTART,
+                SHIFT_POLICY_HORIZONTAL_RIGHT);
     }
 
-    private void positionTopRight(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
-            int height) {
-        mTmpProposal.set(mAvailableRect.right - width, mAvailableRect.top,
-                mAvailableRect.right, mAvailableRect.top + height);
-        position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_LEFT);
+    private void positionTopRight(TaskRecord task, ArrayList<TaskRecord> tasks,
+            Rect availableRect, int width, int height) {
+        mTmpProposal.set(availableRect.right - width, availableRect.top,
+                availableRect.right, availableRect.top + height);
+        position(task, tasks, availableRect, mTmpProposal, !ALLOW_RESTART,
+                SHIFT_POLICY_HORIZONTAL_LEFT);
     }
 
-    private void positionCenter(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
-            int height) {
-        mTmpProposal.set(mDefaultFreeformStartX, mDefaultFreeformStartY,
-                mDefaultFreeformStartX + width, mDefaultFreeformStartY + height);
-        position(task, tasks, mTmpProposal, ALLOW_RESTART, SHIFT_POLICY_DIAGONAL_DOWN);
+    private void positionCenter(TaskRecord task, ArrayList<TaskRecord> tasks,
+            Rect availableRect, int width, int height) {
+        final int defaultFreeformLeft = getFreeformStartLeft(availableRect);
+        final int defaultFreeformTop = getFreeformStartTop(availableRect);
+        mTmpProposal.set(defaultFreeformLeft, defaultFreeformTop,
+                defaultFreeformLeft + width, defaultFreeformTop + height);
+        position(task, tasks, availableRect, mTmpProposal, ALLOW_RESTART,
+                SHIFT_POLICY_DIAGONAL_DOWN);
     }
 
-    private void position(TaskRecord task, ArrayList<TaskRecord> tasks, Rect proposal,
-            boolean allowRestart, int shiftPolicy) {
+    private void position(TaskRecord task, ArrayList<TaskRecord> tasks, Rect availableRect,
+            Rect proposal, boolean allowRestart, int shiftPolicy) {
         mTmpOriginal.set(proposal);
         boolean restarted = false;
         while (boundsConflict(proposal, tasks)) {
             // Unfortunately there is already a task at that spot, so we need to look for some
             // other place.
-            shiftStartingPoint(proposal, shiftPolicy);
-            if (shiftedToFar(proposal, shiftPolicy)) {
+            shiftStartingPoint(proposal, availableRect, shiftPolicy);
+            if (shiftedTooFar(proposal, availableRect, shiftPolicy)) {
                 // We don't want the task to go outside of the stack, because it won't look
                 // nice. Depending on the starting point we either restart, or immediately give up.
                 if (!allowRestart) {
@@ -220,13 +238,13 @@
                 }
                 // We must have started not from the top. Let's restart from there because there
                 // might be some space there.
-                proposal.set(mAvailableRect.left, mAvailableRect.top,
-                        mAvailableRect.left + proposal.width(),
-                        mAvailableRect.top + proposal.height());
+                proposal.set(availableRect.left, availableRect.top,
+                        availableRect.left + proposal.width(),
+                        availableRect.top + proposal.height());
                 restarted = true;
             }
-            if (restarted && (proposal.left > mDefaultFreeformStartX
-                    || proposal.top > mDefaultFreeformStartY)) {
+            if (restarted && (proposal.left > getFreeformStartLeft(availableRect)
+                    || proposal.top > getFreeformStartTop(availableRect))) {
                 // If we restarted and crossed the initial position, let's not struggle anymore.
                 // The user already must have ton of tasks visible, we can just smack the new
                 // one in the center.
@@ -237,27 +255,30 @@
         task.updateOverrideConfiguration(proposal);
     }
 
-    private boolean shiftedToFar(Rect start, int shiftPolicy) {
+    private boolean shiftedTooFar(Rect start, Rect availableRect, int shiftPolicy) {
         switch (shiftPolicy) {
             case SHIFT_POLICY_HORIZONTAL_LEFT:
-                return start.left < mAvailableRect.left;
+                return start.left < availableRect.left;
             case SHIFT_POLICY_HORIZONTAL_RIGHT:
-                return start.right > mAvailableRect.right;
+                return start.right > availableRect.right;
             default: // SHIFT_POLICY_DIAGONAL_DOWN
-                return start.right > mAvailableRect.right || start.bottom > mAvailableRect.bottom;
+                return start.right > availableRect.right || start.bottom > availableRect.bottom;
         }
     }
 
-    private void shiftStartingPoint(Rect posposal, int shiftPolicy) {
+    private void shiftStartingPoint(Rect posposal, Rect availableRect, int shiftPolicy) {
+        final int defaultFreeformStepHorizontal = getHorizontalStep(availableRect);
+        final int defaultFreeformStepVertical = getVerticalStep(availableRect);
+
         switch (shiftPolicy) {
             case SHIFT_POLICY_HORIZONTAL_LEFT:
-                posposal.offset(-mDefaultFreeformStepHorizontal, 0);
+                posposal.offset(-defaultFreeformStepHorizontal, 0);
                 break;
             case SHIFT_POLICY_HORIZONTAL_RIGHT:
-                posposal.offset(mDefaultFreeformStepHorizontal, 0);
+                posposal.offset(defaultFreeformStepHorizontal, 0);
                 break;
             default: // SHIFT_POLICY_DIAGONAL_DOWN:
-                posposal.offset(mDefaultFreeformStepHorizontal, mDefaultFreeformStepVertical);
+                posposal.offset(defaultFreeformStepHorizontal, defaultFreeformStepVertical);
                 break;
         }
     }
@@ -296,8 +317,4 @@
         return Math.abs(first.right - second.right) < BOUNDS_CONFLICT_MIN_DISTANCE
                 && Math.abs(first.bottom - second.bottom) < BOUNDS_CONFLICT_MIN_DISTANCE;
     }
-
-    void reset() {
-        mDefaultStartBoundsConfigurationSet = false;
-    }
 }
diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java
index 72b5de8..940f905 100644
--- a/services/core/java/com/android/server/am/LockTaskController.java
+++ b/services/core/java/com/android/server/am/LockTaskController.java
@@ -19,7 +19,6 @@
 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
 import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.StatusBarManager.DISABLE_BACK;
 import static android.app.StatusBarManager.DISABLE_HOME;
 import static android.app.StatusBarManager.DISABLE_MASK;
@@ -59,7 +58,6 @@
 import android.util.Slog;
 import android.util.SparseArray;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.widget.LockPatternUtils;
@@ -433,7 +431,7 @@
             mWindowManager.executeAppTransition();
         } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
             mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
-                    DEFAULT_DISPLAY, task.getStackId(), true /* forceNonResizable */);
+                    DEFAULT_DISPLAY, task.getStack(), true /* forceNonResizable */);
         }
     }
 
@@ -494,11 +492,7 @@
         }
 
         for (int displayNdx = mSupervisor.getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            ArrayList<ActivityStack> stacks = mSupervisor.getChildAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
-                stack.onLockTaskPackagesUpdatedLocked();
-            }
+            mSupervisor.getChildAt(displayNdx).onLockTaskPackagesUpdated();
         }
 
         final ActivityRecord r = mSupervisor.topRunningActivityLocked();
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 0e318d9..e847723 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -27,6 +27,7 @@
 import com.android.internal.app.procstats.ProcessStats;
 import com.android.internal.app.procstats.ProcessState;
 import com.android.internal.os.BatteryStatsImpl;
+import com.android.server.am.proto.ProcessRecordProto;
 
 import android.app.ActivityManager;
 import android.app.Dialog;
@@ -44,6 +45,7 @@
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -621,6 +623,22 @@
         }
     }
 
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+        long token = proto.start(fieldId);
+        proto.write(ProcessRecordProto.PID, pid);
+        proto.write(ProcessRecordProto.PROCESS_NAME, processName);
+        if (info.uid < Process.FIRST_APPLICATION_UID) {
+            proto.write(ProcessRecordProto.UID, uid);
+        } else {
+            proto.write(ProcessRecordProto.USER_ID, userId);
+            proto.write(ProcessRecordProto.APP_ID, UserHandle.getAppId(info.uid));
+            if (uid != info.uid) {
+                proto.write(ProcessRecordProto.ISOLATED_APP_ID, UserHandle.getAppId(uid));
+            }
+        }
+        proto.end(token);
+    }
+
     public String toShortString() {
         if (shortStringName != null) {
             return shortStringName;
diff --git a/services/core/java/com/android/server/am/ReceiverList.java b/services/core/java/com/android/server/am/ReceiverList.java
index 6ade736..a989063 100644
--- a/services/core/java/com/android/server/am/ReceiverList.java
+++ b/services/core/java/com/android/server/am/ReceiverList.java
@@ -21,6 +21,8 @@
 import android.os.IBinder;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
+import android.util.proto.ProtoOutputStream;
+import com.android.server.am.proto.ReceiverListProto;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -41,7 +43,7 @@
     boolean linkedToDeath = false;
 
     String stringName;
-    
+
     ReceiverList(ActivityManagerService _owner, ProcessRecord _app,
             int _pid, int _uid, int _userId, IIntentReceiver _receiver) {
         owner = _owner;
@@ -59,12 +61,31 @@
     public int hashCode() {
         return System.identityHashCode(this);
     }
-    
+
     public void binderDied() {
         linkedToDeath = false;
         owner.unregisterReceiver(receiver);
     }
-    
+
+    void writeToProto(ProtoOutputStream proto, long fieldId) {
+        long token = proto.start(fieldId);
+        app.writeToProto(proto, ReceiverListProto.APP);
+        proto.write(ReceiverListProto.PID, pid);
+        proto.write(ReceiverListProto.UID, uid);
+        proto.write(ReceiverListProto.USER, userId);
+        if (curBroadcast != null) {
+            curBroadcast.writeToProto(proto, ReceiverListProto.CURRENT);
+        }
+        proto.write(ReceiverListProto.LINKED_TO_DEATH, linkedToDeath);
+        final int N = size();
+        for (int i=0; i<N; i++) {
+            BroadcastFilter bf = get(i);
+            bf.writeToProto(proto, ReceiverListProto.FILTERS);
+        }
+        proto.write(ReceiverListProto.HEX_HASH, Integer.toHexString(System.identityHashCode(this)));
+        proto.end(token);
+    }
+
     void dumpLocal(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("app="); pw.print(app != null ? app.toShortString() : null);
             pw.print(" pid="); pw.print(pid); pw.print(" uid="); pw.print(uid);
@@ -74,7 +95,7 @@
                 pw.print(" linkedToDeath="); pw.println(linkedToDeath);
         }
     }
-    
+
     void dump(PrintWriter pw, String prefix) {
         Printer pr = new PrintWriterPrinter(pw);
         dumpLocal(pw, prefix);
@@ -89,7 +110,7 @@
             bf.dumpInReceiverList(pw, pr, p2);
         }
     }
-    
+
     public String toString() {
         if (stringName != null) {
             return stringName;
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 365c5b1..78274bd 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -16,15 +16,25 @@
 
 package com.android.server.am;
 
+import static android.app.ActivityManager.FLAG_AND_UNLOCKED;
+import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
+import static android.app.ActivityManager.RECENT_WITH_EXCLUDED;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS_TRIM_TASKS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
 
 import com.google.android.collect.Sets;
@@ -37,43 +47,87 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.os.Bundle;
 import android.os.Environment;
+import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.util.ArraySet;
+import android.util.MutableBoolean;
+import android.util.MutableInt;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.am.ActivityStack.ActivityState;
+
 import java.io.File;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 /**
- * Class for managing the recent tasks list.
+ * Class for managing the recent tasks list. The list is ordered by most recent (index 0) to the
+ * least recent.
  */
-class RecentTasks extends ArrayList<TaskRecord> {
+class RecentTasks {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "RecentTasks" : TAG_AM;
     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
     private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
+    private static final boolean TRIMMED = true;
 
-    // Maximum number recent bitmaps to keep in memory.
-    private static final int MAX_RECENT_BITMAPS = 3;
     private static final int DEFAULT_INITIAL_CAPACITY = 5;
 
     // Whether or not to move all affiliated tasks to the front when one of the tasks is launched
     private static final boolean MOVE_AFFILIATED_TASKS_TO_FRONT = false;
 
+    // Comparator to sort by taskId
+    private static final Comparator<TaskRecord> TASK_ID_COMPARATOR =
+            (lhs, rhs) -> rhs.taskId - lhs.taskId;
+
+    // Placeholder variables to keep track of activities/apps that are no longer avialble while
+    // iterating through the recents list
+    private static final ActivityInfo NO_ACTIVITY_INFO_TOKEN = new ActivityInfo();
+    private static final ApplicationInfo NO_APPLICATION_INFO_TOKEN = new ApplicationInfo();
+
+    /**
+     * Callbacks made when manipulating the list.
+     */
+    interface Callbacks {
+        /**
+         * Called when a task is added to the recent tasks list.
+         */
+        void onRecentTaskAdded(TaskRecord task);
+
+        /**
+         * Called when a task is removed from the recent tasks list.
+         */
+        void onRecentTaskRemoved(TaskRecord task, boolean wasTrimmed);
+    }
+
     /**
      * Save recent tasks information across reboots.
      */
     private final TaskPersister mTaskPersister;
     private final ActivityManagerService mService;
+    private final UserController mUserController;
+
+    /**
+     * Mapping of user id -> whether recent tasks have been loaded for that user.
+     */
     private final SparseBooleanArray mUsersWithRecentsLoaded = new SparseBooleanArray(
             DEFAULT_INITIAL_CAPACITY);
 
@@ -81,21 +135,106 @@
      * Stores for each user task ids that are taken by tasks residing in persistent storage. These
      * tasks may or may not currently be in memory.
      */
-    final SparseArray<SparseBooleanArray> mPersistedTaskIds = new SparseArray<>(
+    private final SparseArray<SparseBooleanArray> mPersistedTaskIds = new SparseArray<>(
             DEFAULT_INITIAL_CAPACITY);
 
+    // List of all active recent tasks
+    private final ArrayList<TaskRecord> mTasks = new ArrayList<>();
+    private final ArrayList<Callbacks> mCallbacks = new ArrayList<>();
+
+    // These values are generally loaded from resources, but can be set dynamically in the tests
+    private boolean mHasVisibleRecentTasks;
+    private int mGlobalMaxNumTasks;
+    private int mMinNumVisibleTasks;
+    private int mMaxNumVisibleTasks;
+    private long mActiveTasksSessionDurationMs;
+
     // Mainly to avoid object recreation on multiple calls.
-    private final ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
+    private final ArrayList<TaskRecord> mTmpRecents = new ArrayList<>();
     private final HashMap<ComponentName, ActivityInfo> mTmpAvailActCache = new HashMap<>();
     private final HashMap<String, ApplicationInfo> mTmpAvailAppCache = new HashMap<>();
-    private final ActivityInfo mTmpActivityInfo = new ActivityInfo();
-    private final ApplicationInfo mTmpAppInfo = new ApplicationInfo();
+    private final SparseBooleanArray mTmpQuietProfileUserIds = new SparseBooleanArray();
 
-    RecentTasks(ActivityManagerService service, ActivityStackSupervisor mStackSupervisor) {
-        File systemDir = Environment.getDataSystemDirectory();
+    @VisibleForTesting
+    RecentTasks(ActivityManagerService service, TaskPersister taskPersister,
+            UserController userController) {
         mService = service;
-        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, service, this);
-        mStackSupervisor.setRecentTasks(this);
+        mUserController = userController;
+        mTaskPersister = taskPersister;
+        mGlobalMaxNumTasks = ActivityManager.getMaxRecentTasksStatic();
+        mHasVisibleRecentTasks = true;
+    }
+
+    RecentTasks(ActivityManagerService service, ActivityStackSupervisor stackSupervisor) {
+        final File systemDir = Environment.getDataSystemDirectory();
+        final Resources res = service.mContext.getResources();
+        mService = service;
+        mUserController = service.mUserController;
+        mTaskPersister = new TaskPersister(systemDir, stackSupervisor, service, this);
+        mGlobalMaxNumTasks = ActivityManager.getMaxRecentTasksStatic();
+        mHasVisibleRecentTasks = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
+        loadParametersFromResources(service.mContext.getResources());
+    }
+
+    @VisibleForTesting
+    void setParameters(int minNumVisibleTasks, int maxNumVisibleTasks,
+            long activeSessionDurationMs) {
+        mMinNumVisibleTasks = minNumVisibleTasks;
+        mMaxNumVisibleTasks = maxNumVisibleTasks;
+        mActiveTasksSessionDurationMs = activeSessionDurationMs;
+    }
+
+    @VisibleForTesting
+    void setGlobalMaxNumTasks(int globalMaxNumTasks) {
+        mGlobalMaxNumTasks = globalMaxNumTasks;
+    }
+
+    /**
+     * Loads the parameters from the system resources.
+     */
+    @VisibleForTesting
+    void loadParametersFromResources(Resources res) {
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            mMinNumVisibleTasks = res.getInteger(
+                    com.android.internal.R.integer.config_minNumVisibleRecentTasks_lowRam);
+            mMaxNumVisibleTasks = res.getInteger(
+                    com.android.internal.R.integer.config_maxNumVisibleRecentTasks_lowRam);
+        } else if (SystemProperties.getBoolean("ro.recents.grid", false)) {
+            mMinNumVisibleTasks = res.getInteger(
+                    com.android.internal.R.integer.config_minNumVisibleRecentTasks_grid);
+            mMaxNumVisibleTasks = res.getInteger(
+                    com.android.internal.R.integer.config_maxNumVisibleRecentTasks_grid);
+        } else {
+            mMinNumVisibleTasks = res.getInteger(
+                    com.android.internal.R.integer.config_minNumVisibleRecentTasks);
+            mMaxNumVisibleTasks = res.getInteger(
+                    com.android.internal.R.integer.config_maxNumVisibleRecentTasks);
+        }
+        final int sessionDurationHrs = res.getInteger(
+                com.android.internal.R.integer.config_activeTaskDurationHours);
+        mActiveTasksSessionDurationMs = (sessionDurationHrs > 0)
+                ? TimeUnit.HOURS.toMillis(sessionDurationHrs)
+                : -1;
+    }
+
+    void registerCallback(Callbacks callback) {
+        mCallbacks.add(callback);
+    }
+
+    void unregisterCallback(Callbacks callback) {
+        mCallbacks.remove(callback);
+    }
+
+    private void notifyTaskAdded(TaskRecord task) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            mCallbacks.get(i).onRecentTaskAdded(task);
+        }
+    }
+
+    private void notifyTaskRemoved(TaskRecord task, boolean wasTrimmed) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            mCallbacks.get(i).onRecentTaskRemoved(task, wasTrimmed);
+        }
     }
 
     /**
@@ -106,6 +245,7 @@
      */
     void loadUserRecentsLocked(int userId) {
         if (mUsersWithRecentsLoaded.get(userId)) {
+            // User already loaded, return early
             return;
         }
 
@@ -114,14 +254,14 @@
 
         // Check if any tasks are added before recents is loaded
         final SparseBooleanArray preaddedTasks = new SparseBooleanArray();
-        for (final TaskRecord task : this) {
+        for (final TaskRecord task : mTasks) {
             if (task.userId == userId && shouldPersistTaskLocked(task)) {
                 preaddedTasks.put(task.taskId, true);
             }
         }
 
         Slog.i(TAG, "Loading recents for user " + userId + " into memory.");
-        addAll(mTaskPersister.restoreTasksForUserLocked(userId, preaddedTasks));
+        mTasks.addAll(mTaskPersister.restoreTasksForUserLocked(userId, preaddedTasks));
         cleanupLocked(userId);
         mUsersWithRecentsLoaded.put(userId, true);
 
@@ -140,11 +280,25 @@
         }
     }
 
-    boolean taskIdTakenForUserLocked(int taskId, int userId) {
+    /**
+     * @return whether the {@param taskId} is currently in use for the given user.
+     */
+    boolean containsTaskId(int taskId, int userId) {
         loadPersistedTaskIdsForUserLocked(userId);
         return mPersistedTaskIds.get(userId).get(taskId);
     }
 
+    /**
+     * @return all the task ids for the user with the given {@param userId}.
+     */
+    SparseBooleanArray getTaskIdsForUser(int userId) {
+        loadPersistedTaskIdsForUserLocked(userId);
+        return mPersistedTaskIds.get(userId);
+    }
+
+    /**
+     * Kicks off the task persister to write any pending tasks to disk.
+     */
     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
         final ActivityStack stack = task != null ? task.getStack() : null;
         if (stack != null && stack.isHomeOrRecentsStack()) {
@@ -164,8 +318,8 @@
                 mPersistedTaskIds.valueAt(i).clear();
             }
         }
-        for (int i = size() - 1; i >= 0; i--) {
-            final TaskRecord task = get(i);
+        for (int i = mTasks.size() - 1; i >= 0; i--) {
+            final TaskRecord task = mTasks.get(i);
             if (shouldPersistTaskLocked(task)) {
                 // Set of persisted taskIds for task.userId should not be null here
                 // TODO Investigate why it can happen. For now initialize with an empty set
@@ -180,12 +334,12 @@
     }
 
     private static boolean shouldPersistTaskLocked(TaskRecord task) {
-        final ActivityStack<?> stack = task.getStack();
+        final ActivityStack stack = task.getStack();
         return task.isPersistable && (stack == null || !stack.isHomeOrRecentsStack());
     }
 
     void onSystemReadyLocked() {
-        clear();
+        mTasks.clear();
         mTaskPersister.startPersisting();
     }
 
@@ -225,14 +379,6 @@
         return usersWithRecentsLoaded;
     }
 
-    private void unloadUserRecentsLocked(int userId) {
-        if (mUsersWithRecentsLoaded.get(userId)) {
-            Slog.i(TAG, "Unloading recents for user " + userId + " from memory.");
-            mUsersWithRecentsLoaded.delete(userId);
-            removeTasksForUserLocked(userId);
-        }
-    }
-
     /**
      * Removes recent tasks and any other state kept in memory for the passed in user. Does not
      * touch the information present on persistent storage.
@@ -240,44 +386,36 @@
      * @param userId the id of the user
      */
     void unloadUserDataFromMemoryLocked(int userId) {
-        unloadUserRecentsLocked(userId);
+        if (mUsersWithRecentsLoaded.get(userId)) {
+            Slog.i(TAG, "Unloading recents for user " + userId + " from memory.");
+            mUsersWithRecentsLoaded.delete(userId);
+            removeTasksForUserLocked(userId);
+        }
         mPersistedTaskIds.delete(userId);
         mTaskPersister.unloadUserDataFromMemory(userId);
     }
 
-    TaskRecord taskForIdLocked(int id) {
-        final int recentsCount = size();
-        for (int i = 0; i < recentsCount; i++) {
-            TaskRecord tr = get(i);
-            if (tr.taskId == id) {
-                return tr;
-            }
-        }
-        return null;
-    }
-
     /** Remove recent tasks for a user. */
-    void removeTasksForUserLocked(int userId) {
+    private void removeTasksForUserLocked(int userId) {
         if(userId <= 0) {
             Slog.i(TAG, "Can't remove recent task on user " + userId);
             return;
         }
 
-        for (int i = size() - 1; i >= 0; --i) {
-            TaskRecord tr = get(i);
+        for (int i = mTasks.size() - 1; i >= 0; --i) {
+            TaskRecord tr = mTasks.get(i);
             if (tr.userId == userId) {
                 if(DEBUG_TASKS) Slog.i(TAG_TASKS,
                         "remove RecentTask " + tr + " when finishing user" + userId);
-                remove(i);
-                tr.removedFromRecents();
+                remove(mTasks.get(i));
             }
         }
     }
 
     void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) {
         final Set<String> packageNames = Sets.newHashSet(packages);
-        for (int i = size() - 1; i >= 0; --i) {
-            final TaskRecord tr = get(i);
+        for (int i = mTasks.size() - 1; i >= 0; --i) {
+            final TaskRecord tr = mTasks.get(i);
             if (tr.realActivity != null
                     && packageNames.contains(tr.realActivity.getPackageName())
                     && tr.userId == userId
@@ -286,7 +424,36 @@
                notifyTaskPersisterLocked(tr, false);
             }
         }
+    }
 
+    void removeTasksByPackageName(String packageName, int userId) {
+        for (int i = mTasks.size() - 1; i >= 0; --i) {
+            final TaskRecord tr = mTasks.get(i);
+            final String taskPackageName =
+                    tr.getBaseIntent().getComponent().getPackageName();
+            if (tr.userId != userId) return;
+            if (!taskPackageName.equals(packageName)) return;
+
+            mService.mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
+        }
+    }
+
+    void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
+            int userId) {
+        for (int i = mTasks.size() - 1; i >= 0; --i) {
+            final TaskRecord tr = mTasks.get(i);
+            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
+                continue;
+            }
+
+            ComponentName cn = tr.intent.getComponent();
+            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
+                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
+            if (sameComponent) {
+                mService.mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
+                        REMOVE_FROM_RECENTS);
+            }
+        }
     }
 
     /**
@@ -295,24 +462,28 @@
      * of affiliations.
      */
     void cleanupLocked(int userId) {
-        int recentsCount = size();
+        int recentsCount = mTasks.size();
         if (recentsCount == 0) {
             // Happens when called from the packagemanager broadcast before boot,
             // or just any empty list.
             return;
         }
 
+        // Clear the temp lists
+        mTmpAvailActCache.clear();
+        mTmpAvailAppCache.clear();
+
         final IPackageManager pm = AppGlobals.getPackageManager();
         for (int i = recentsCount - 1; i >= 0; i--) {
-            final TaskRecord task = get(i);
+            final TaskRecord task = mTasks.get(i);
             if (userId != UserHandle.USER_ALL && task.userId != userId) {
                 // Only look at tasks for the user ID of interest.
                 continue;
             }
             if (task.autoRemoveRecents && task.getTopActivity() == null) {
                 // This situation is broken, and we should just get rid of it now.
-                remove(i);
-                task.removedFromRecents();
+                mTasks.remove(i);
+                notifyTaskRemoved(task, !TRIMMED);
                 Slog.w(TAG, "Removing auto-remove without activity: " + task);
                 continue;
             }
@@ -331,11 +502,11 @@
                         continue;
                     }
                     if (ai == null) {
-                        ai = mTmpActivityInfo;
+                        ai = NO_ACTIVITY_INFO_TOKEN;
                     }
                     mTmpAvailActCache.put(task.realActivity, ai);
                 }
-                if (ai == mTmpActivityInfo) {
+                if (ai == NO_ACTIVITY_INFO_TOKEN) {
                     // This could be either because the activity no longer exists, or the
                     // app is temporarily gone. For the former we want to remove the recents
                     // entry; for the latter we want to mark it as unavailable.
@@ -350,15 +521,15 @@
                             continue;
                         }
                         if (app == null) {
-                            app = mTmpAppInfo;
+                            app = NO_APPLICATION_INFO_TOKEN;
                         }
                         mTmpAvailAppCache.put(task.realActivity.getPackageName(), app);
                     }
-                    if (app == mTmpAppInfo
+                    if (app == NO_APPLICATION_INFO_TOKEN
                             || (app.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
                         // Doesn't exist any more! Good-bye.
-                        remove(i);
-                        task.removedFromRecents();
+                        mTasks.remove(i);
+                        notifyTaskRemoved(task, !TRIMMED);
                         Slog.w(TAG, "Removing no longer valid recent: " + task);
                         continue;
                     } else {
@@ -390,15 +561,670 @@
 
         // Verify the affiliate chain for each task.
         int i = 0;
-        recentsCount = size();
+        recentsCount = mTasks.size();
         while (i < recentsCount) {
             i = processNextAffiliateChainLocked(i);
         }
         // recent tasks are now in sorted, affiliated order.
     }
 
-    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
-        int recentsCount = size();
+    /**
+     * @return whether the given {@param task} can be added to the list without causing another
+     * task to be trimmed as a result of that add.
+     */
+    private boolean canAddTaskWithoutTrim(TaskRecord task) {
+        return findTrimIndexForAddTask(task) == -1;
+    }
+
+    /**
+     * Returns the list of {@link ActivityManager.AppTask}s.
+     */
+    ArrayList<IBinder> getAppTasksList(int callingUid, String callingPackage) {
+        final ArrayList<IBinder> list = new ArrayList<>();
+        final int size = mTasks.size();
+        for (int i = 0; i < size; i++) {
+            final TaskRecord tr = mTasks.get(i);
+            // Skip tasks that do not match the caller.  We don't need to verify
+            // callingPackage, because we are also limiting to callingUid and know
+            // that will limit to the correct security sandbox.
+            if (tr.effectiveUid != callingUid) {
+                continue;
+            }
+            Intent intent = tr.getBaseIntent();
+            if (intent == null || !callingPackage.equals(intent.getComponent().getPackageName())) {
+                continue;
+            }
+            ActivityManager.RecentTaskInfo taskInfo = createRecentTaskInfo(tr);
+            AppTaskImpl taskImpl = new AppTaskImpl(mService, taskInfo.persistentId, callingUid);
+            list.add(taskImpl.asBinder());
+        }
+        return list;
+    }
+
+    /**
+     * @return the list of recent tasks for presentation.
+     */
+    ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
+            boolean getTasksAllowed, boolean getDetailedTasks, int userId, int callingUid) {
+        final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0;
+
+        if (!mService.isUserRunning(userId, FLAG_AND_UNLOCKED)) {
+            Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
+            return ParceledListSlice.emptyList();
+        }
+        loadUserRecentsLocked(userId);
+
+        final Set<Integer> includedUsers = mUserController.getProfileIds(userId);
+        includedUsers.add(Integer.valueOf(userId));
+
+        final ArrayList<ActivityManager.RecentTaskInfo> res = new ArrayList<>();
+        final int size = mTasks.size();
+        int numVisibleTasks = 0;
+        for (int i = 0; i < size; i++) {
+            final TaskRecord tr = mTasks.get(i);
+
+            if (isVisibleRecentTask(tr)) {
+                numVisibleTasks++;
+                if (isInVisibleRange(tr, numVisibleTasks)) {
+                    // Fall through
+                } else {
+                    // Not in visible range
+                    continue;
+                }
+            } else {
+                // Not visible
+                continue;
+            }
+
+            // Skip remaining tasks once we reach the requested size
+            if (res.size() >= maxNum) {
+                continue;
+            }
+
+            // Only add calling user or related users recent tasks
+            if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
+                if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
+                continue;
+            }
+
+            if (tr.realActivitySuspended) {
+                if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
+                continue;
+            }
+
+            // Return the entry if desired by the caller.  We always return
+            // the first entry, because callers always expect this to be the
+            // foreground app.  We may filter others if the caller has
+            // not supplied RECENT_WITH_EXCLUDED and there is some reason
+            // we should exclude the entry.
+
+            if (i == 0
+                    || withExcluded
+                    || (tr.intent == null)
+                    || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+                    == 0)) {
+                if (!getTasksAllowed) {
+                    // If the caller doesn't have the GET_TASKS permission, then only
+                    // allow them to see a small subset of tasks -- their own and home.
+                    if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
+                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
+                        continue;
+                    }
+                }
+                if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
+                    // Don't include auto remove tasks that are finished or finishing.
+                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
+                            "Skipping, auto-remove without activity: " + tr);
+                    continue;
+                }
+                if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) {
+                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
+                            "Skipping, unavail real act: " + tr);
+                    continue;
+                }
+
+                if (!tr.mUserSetupComplete) {
+                    // Don't include task launched while user is not done setting-up.
+                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
+                            "Skipping, user setup not complete: " + tr);
+                    continue;
+                }
+
+                ActivityManager.RecentTaskInfo rti = RecentTasks.createRecentTaskInfo(tr);
+                if (!getDetailedTasks) {
+                    rti.baseIntent.replaceExtras((Bundle)null);
+                }
+
+                res.add(rti);
+            }
+        }
+        return new ParceledListSlice<>(res);
+    }
+
+    /**
+     * @return the list of persistable task ids.
+     */
+    void getPersistableTaskIds(ArraySet<Integer> persistentTaskIds) {
+        final int size = mTasks.size();
+        for (int i = 0; i < size; i++) {
+            final TaskRecord task = mTasks.get(i);
+            if (TaskPersister.DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task
+                    + " persistable=" + task.isPersistable);
+            final ActivityStack stack = task.getStack();
+            if ((task.isPersistable || task.inRecents)
+                    && (stack == null || !stack.isHomeOrRecentsStack())) {
+                if (TaskPersister.DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task);
+                persistentTaskIds.add(task.taskId);
+            } else {
+                if (TaskPersister.DEBUG) Slog.d(TAG, "omitting from persistentTaskIds task="
+                        + task);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    ArrayList<TaskRecord> getRawTasks() {
+        return mTasks;
+    }
+
+    /**
+     * @return the task in the task list with the given {@param id} if one exists.
+     */
+    TaskRecord getTask(int id) {
+        final int recentsCount = mTasks.size();
+        for (int i = 0; i < recentsCount; i++) {
+            TaskRecord tr = mTasks.get(i);
+            if (tr.taskId == id) {
+                return tr;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Add a new task to the recent tasks list.
+     */
+    void add(TaskRecord task) {
+        if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "add: task=" + task);
+
+        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
+                || task.mNextAffiliateTaskId != INVALID_TASK_ID
+                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
+
+        int recentsCount = mTasks.size();
+        // Quick case: never add voice sessions.
+        // TODO: VI what about if it's just an activity?
+        // Probably nothing to do here
+        if (task.voiceSession != null) {
+            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
+                    "addRecent: not adding voice interaction " + task);
+            return;
+        }
+        // Another quick case: check if the top-most recent task is the same.
+        if (!isAffiliated && recentsCount > 0 && mTasks.get(0) == task) {
+            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: already at top: " + task);
+            return;
+        }
+        // Another quick case: check if this is part of a set of affiliated
+        // tasks that are at the top.
+        if (isAffiliated && recentsCount > 0 && task.inRecents
+                && task.mAffiliatedTaskId == mTasks.get(0).mAffiliatedTaskId) {
+            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: affiliated " + mTasks.get(0)
+                    + " at top when adding " + task);
+            return;
+        }
+
+        boolean needAffiliationFix = false;
+
+        // Slightly less quick case: the task is already in recents, so all we need
+        // to do is move it.
+        if (task.inRecents) {
+            int taskIndex = mTasks.indexOf(task);
+            if (taskIndex >= 0) {
+                if (!isAffiliated || !MOVE_AFFILIATED_TASKS_TO_FRONT) {
+                    // Simple case: this is not an affiliated task, so we just move it to the front.
+                    mTasks.remove(taskIndex);
+                    mTasks.add(0, task);
+                    notifyTaskPersisterLocked(task, false);
+                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: moving to top " + task
+                            + " from " + taskIndex);
+                    return;
+                } else {
+                    // More complicated: need to keep all affiliated tasks together.
+                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
+                        // All went well.
+                        return;
+                    }
+
+                    // Uh oh...  something bad in the affiliation chain, try to rebuild
+                    // everything and then go through our general path of adding a new task.
+                    needAffiliationFix = true;
+                }
+            } else {
+                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
+                needAffiliationFix = true;
+            }
+        }
+
+        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: trimming tasks for " + task);
+        trimForAddTask(task);
+
+        task.inRecents = true;
+        if (!isAffiliated || needAffiliationFix) {
+            // If this is a simple non-affiliated task, or we had some failure trying to
+            // handle it as part of an affilated task, then just place it at the top.
+            mTasks.add(0, task);
+            notifyTaskAdded(task);
+            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: adding " + task);
+        } else if (isAffiliated) {
+            // If this is a new affiliated task, then move all of the affiliated tasks
+            // to the front and insert this new one.
+            TaskRecord other = task.mNextAffiliate;
+            if (other == null) {
+                other = task.mPrevAffiliate;
+            }
+            if (other != null) {
+                int otherIndex = mTasks.indexOf(other);
+                if (otherIndex >= 0) {
+                    // Insert new task at appropriate location.
+                    int taskIndex;
+                    if (other == task.mNextAffiliate) {
+                        // We found the index of our next affiliation, which is who is
+                        // before us in the list, so add after that point.
+                        taskIndex = otherIndex+1;
+                    } else {
+                        // We found the index of our previous affiliation, which is who is
+                        // after us in the list, so add at their position.
+                        taskIndex = otherIndex;
+                    }
+                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
+                            "addRecent: new affiliated task added at " + taskIndex + ": " + task);
+                    mTasks.add(taskIndex, task);
+                    notifyTaskAdded(task);
+
+                    // Now move everything to the front.
+                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
+                        // All went well.
+                        return;
+                    }
+
+                    // Uh oh...  something bad in the affiliation chain, try to rebuild
+                    // everything and then go through our general path of adding a new task.
+                    needAffiliationFix = true;
+                } else {
+                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
+                            "addRecent: couldn't find other affiliation " + other);
+                    needAffiliationFix = true;
+                }
+            } else {
+                if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
+                        "addRecent: adding affiliated task without next/prev:" + task);
+                needAffiliationFix = true;
+            }
+        }
+
+        if (needAffiliationFix) {
+            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: regrouping affiliations");
+            cleanupLocked(task.userId);
+        }
+
+        // Trim the set of tasks to the active set
+        trimInactiveRecentTasks();
+    }
+
+    /**
+     * Add the task to the bottom if possible.
+     */
+    boolean addToBottom(TaskRecord task) {
+        if (!canAddTaskWithoutTrim(task)) {
+            // Adding this task would cause the task to be removed (since it's appended at
+            // the bottom and would be trimmed) so just return now
+            return false;
+        }
+
+        add(task);
+        return true;
+    }
+
+    /**
+     * Remove a task from the recent tasks list.
+     */
+    void remove(TaskRecord task) {
+        mTasks.remove(task);
+        notifyTaskRemoved(task, !TRIMMED);
+    }
+
+    /**
+     * Trims the recents task list to the global max number of recents.
+     */
+    private void trimInactiveRecentTasks() {
+        int recentsCount = mTasks.size();
+
+        // Remove from the end of the list until we reach the max number of recents
+        while (recentsCount > mGlobalMaxNumTasks) {
+            final TaskRecord tr = mTasks.remove(recentsCount - 1);
+            notifyTaskRemoved(tr, TRIMMED);
+            recentsCount--;
+            if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "Trimming over max-recents task=" + tr
+                    + " max=" + mGlobalMaxNumTasks);
+        }
+
+        // Remove any tasks that belong to currently quiet profiles
+        final int[] profileUserIds = mUserController.getCurrentProfileIds();
+        mTmpQuietProfileUserIds.clear();
+        for (int userId : profileUserIds) {
+            final UserInfo userInfo = mUserController.getUserInfo(userId);
+            if (userInfo.isManagedProfile() && userInfo.isQuietModeEnabled()) {
+                mTmpQuietProfileUserIds.put(userId, true);
+            }
+            if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "User: " + userInfo
+                    + " quiet=" + mTmpQuietProfileUserIds.get(userId));
+        }
+
+        // Remove any inactive tasks, calculate the latest set of visible tasks
+        int numVisibleTasks = 0;
+        for (int i = 0; i < mTasks.size();) {
+            final TaskRecord task = mTasks.get(i);
+
+            if (isActiveRecentTask(task, mTmpQuietProfileUserIds)) {
+                if (!mHasVisibleRecentTasks) {
+                    // Keep all active tasks if visible recent tasks is not supported
+                    i++;
+                    continue;
+                }
+
+                if (!isVisibleRecentTask(task)) {
+                    // Keep all active-but-invisible tasks
+                    i++;
+                    continue;
+                } else {
+                    numVisibleTasks++;
+                    if (isInVisibleRange(task, numVisibleTasks)) {
+                        // Keep visible tasks in range
+                        i++;
+                        continue;
+                    } else {
+                        // Fall through to trim visible tasks that are no longer in range
+                        if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG,
+                                "Trimming out-of-range visible task=" + task);
+                    }
+                }
+            } else {
+                // Fall through to trim inactive tasks
+                if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "Trimming inactive task=" + task);
+            }
+
+            // Task is no longer active, trim it from the list
+            mTasks.remove(task);
+            notifyTaskRemoved(task, TRIMMED);
+            notifyTaskPersisterLocked(task, false /* flush */);
+        }
+    }
+
+    /**
+     * @return whether the given task should be considered active.
+     */
+    private boolean isActiveRecentTask(TaskRecord task, SparseBooleanArray quietProfileUserIds) {
+        if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "isActiveRecentTask: task=" + task
+                + " globalMax=" + mGlobalMaxNumTasks);
+
+        if (quietProfileUserIds.get(task.userId)) {
+            // Quiet profile user's tasks are never active
+            if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\tisQuietProfileTask=true");
+            return false;
+        }
+
+        if (task.mAffiliatedTaskId != INVALID_TASK_ID && task.mAffiliatedTaskId != task.taskId) {
+            // Keep the task active if its affiliated task is also active
+            final TaskRecord affiliatedTask = getTask(task.mAffiliatedTaskId);
+            if (affiliatedTask != null) {
+                if (!isActiveRecentTask(affiliatedTask, quietProfileUserIds)) {
+                    if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG,
+                            "\taffiliatedWithTask=" + affiliatedTask + " is not active");
+                    return false;
+                }
+            }
+        }
+
+        // All other tasks are considered active
+        return true;
+    }
+
+    /**
+     * @return whether the given active task should be presented to the user through SystemUI.
+     */
+    private boolean isVisibleRecentTask(TaskRecord task) {
+        if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "isVisibleRecentTask: task=" + task
+                + " minVis=" + mMinNumVisibleTasks + " maxVis=" + mMaxNumVisibleTasks
+                + " sessionDuration=" + mActiveTasksSessionDurationMs
+                + " inactiveDuration=" + task.getInactiveDuration()
+                + " activityType=" + task.getActivityType()
+                + " windowingMode=" + task.getWindowingMode());
+
+        // Ignore certain activity types completely
+        switch (task.getActivityType()) {
+            case ACTIVITY_TYPE_HOME:
+            case ACTIVITY_TYPE_RECENTS:
+                return false;
+        }
+
+        // Ignore certain windowing modes
+        switch (task.getWindowingMode()) {
+            case WINDOWING_MODE_PINNED:
+                return false;
+            case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
+                if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\ttop=" + task.getStack().topTask());
+                final ActivityStack stack = task.getStack();
+                if (stack != null && stack.topTask() == task) {
+                    // Only the non-top task of the primary split screen mode is visible
+                    return false;
+                }
+        }
+
+        return true;
+    }
+
+    /**
+     * @return whether the given visible task is within the policy range.
+     */
+    private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks) {
+        // Keep the last most task even if it is excluded from recents
+        final boolean isExcludeFromRecents =
+                (task.getBaseIntent().getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+                        == Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+        if (isExcludeFromRecents) {
+            if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true");
+            return numVisibleTasks == 1;
+        }
+
+        if (mMinNumVisibleTasks >= 0 && numVisibleTasks <= mMinNumVisibleTasks) {
+            // Always keep up to the min number of recent tasks, after that fall through to the
+            // checks below
+            return true;
+        }
+
+        if (mMaxNumVisibleTasks >= 0) {
+            // Always keep up to the max number of recent tasks, but return false afterwards
+            return numVisibleTasks <= mMaxNumVisibleTasks;
+        }
+
+        if (mActiveTasksSessionDurationMs > 0) {
+            // Keep the task if the inactive time is within the session window, this check must come
+            // after the checks for the min/max visible task range
+            if (task.getInactiveDuration() <= mActiveTasksSessionDurationMs) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * If needed, remove oldest existing entries in recents that are for the same kind
+     * of task as the given one.
+     */
+    private void trimForAddTask(TaskRecord task) {
+        final int removeIndex = findTrimIndexForAddTask(task);
+        if (removeIndex == -1) {
+            // Nothing to trim
+            return;
+        }
+
+        // There is a similar task that will be removed for the addition of {@param task}, but it
+        // can be the same task, and if so, the task will be re-added in add(), so skip the
+        // callbacks here.
+        final TaskRecord removedTask = mTasks.remove(removeIndex);
+        if (removedTask != task) {
+            notifyTaskRemoved(removedTask, TRIMMED);
+            if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "Trimming task=" + removedTask
+                    + " for addition of task=" + task);
+        }
+        notifyTaskPersisterLocked(removedTask, false /* flush */);
+    }
+
+    /**
+     * Find the task that would be removed if the given {@param task} is added to the recent tasks
+     * list (if any).
+     */
+    private int findTrimIndexForAddTask(TaskRecord task) {
+        int recentsCount = mTasks.size();
+        final Intent intent = task.intent;
+        final boolean document = intent != null && intent.isDocument();
+        int maxRecents = task.maxRecents - 1;
+        final ActivityStack stack = task.getStack();
+        for (int i = 0; i < recentsCount; i++) {
+            final TaskRecord tr = mTasks.get(i);
+            final ActivityStack trStack = tr.getStack();
+
+            if (task != tr) {
+                if (stack != null && trStack != null && stack != trStack) {
+                    continue;
+                }
+                if (task.userId != tr.userId) {
+                    continue;
+                }
+                final Intent trIntent = tr.intent;
+                final boolean sameAffinity =
+                        task.affinity != null && task.affinity.equals(tr.affinity);
+                final boolean sameIntent = intent != null && intent.filterEquals(trIntent);
+                boolean multiTasksAllowed = false;
+                final int flags = intent.getFlags();
+                if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0
+                        && (flags & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
+                    multiTasksAllowed = true;
+                }
+                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
+                final boolean bothDocuments = document && trIsDocument;
+                if (!sameAffinity && !sameIntent && !bothDocuments) {
+                    continue;
+                }
+
+                if (bothDocuments) {
+                    // Do these documents belong to the same activity?
+                    final boolean sameActivity = task.realActivity != null
+                            && tr.realActivity != null
+                            && task.realActivity.equals(tr.realActivity);
+                    if (!sameActivity) {
+                        // If the document is open in another app or is not the same document, we
+                        // don't need to trim it.
+                        continue;
+                    } else if (maxRecents > 0) {
+                        // Otherwise only trim if we are over our max recents for this task
+                        --maxRecents;
+                        if (!sameIntent || multiTasksAllowed) {
+                            // We don't want to trim if we are not over the max allowed entries and
+                            // the tasks are not of the same intent filter, or multiple entries for
+                            // the task is allowed.
+                            continue;
+                        }
+                    }
+                    // Hit the maximum number of documents for this task. Fall through
+                    // and remove this document from recents.
+                } else if (document || trIsDocument) {
+                    // Only one of these is a document. Not the droid we're looking for.
+                    continue;
+                }
+            }
+            return i;
+        }
+        return -1;
+    }
+
+    // Extract the affiliates of the chain containing recent at index start.
+    private int processNextAffiliateChainLocked(int start) {
+        final TaskRecord startTask = mTasks.get(start);
+        final int affiliateId = startTask.mAffiliatedTaskId;
+
+        // Quick identification of isolated tasks. I.e. those not launched behind.
+        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
+                startTask.mNextAffiliate == null) {
+            // There is still a slim chance that there are other tasks that point to this task
+            // and that the chain is so messed up that this task no longer points to them but
+            // the gain of this optimization outweighs the risk.
+            startTask.inRecents = true;
+            return start + 1;
+        }
+
+        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
+        mTmpRecents.clear();
+        for (int i = mTasks.size() - 1; i >= start; --i) {
+            final TaskRecord task = mTasks.get(i);
+            if (task.mAffiliatedTaskId == affiliateId) {
+                mTasks.remove(i);
+                mTmpRecents.add(task);
+            }
+        }
+
+        // Sort them all by taskId. That is the order they were create in and that order will
+        // always be correct.
+        Collections.sort(mTmpRecents, TASK_ID_COMPARATOR);
+
+        // Go through and fix up the linked list.
+        // The first one is the end of the chain and has no next.
+        final TaskRecord first = mTmpRecents.get(0);
+        first.inRecents = true;
+        if (first.mNextAffiliate != null) {
+            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
+            first.setNextAffiliate(null);
+            notifyTaskPersisterLocked(first, false);
+        }
+        // Everything in the middle is doubly linked from next to prev.
+        final int tmpSize = mTmpRecents.size();
+        for (int i = 0; i < tmpSize - 1; ++i) {
+            final TaskRecord next = mTmpRecents.get(i);
+            final TaskRecord prev = mTmpRecents.get(i + 1);
+            if (next.mPrevAffiliate != prev) {
+                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
+                        " setting prev=" + prev);
+                next.setPrevAffiliate(prev);
+                notifyTaskPersisterLocked(next, false);
+            }
+            if (prev.mNextAffiliate != next) {
+                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
+                        " setting next=" + next);
+                prev.setNextAffiliate(next);
+                notifyTaskPersisterLocked(prev, false);
+            }
+            prev.inRecents = true;
+        }
+        // The last one is the beginning of the list and has no prev.
+        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
+        if (last.mPrevAffiliate != null) {
+            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
+            last.setPrevAffiliate(null);
+            notifyTaskPersisterLocked(last, false);
+        }
+
+        // Insert the group back into mTmpTasks at start.
+        mTasks.addAll(start, mTmpRecents);
+        mTmpRecents.clear();
+
+        // Let the caller know where we left off.
+        return start + tmpSize;
+    }
+
+    private boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
+        int recentsCount = mTasks.size();
         TaskRecord top = task;
         int topIndex = taskIndex;
         while (top.mNextAffiliate != null && topIndex > 0) {
@@ -412,7 +1238,7 @@
         int endIndex = topIndex;
         TaskRecord prev = top;
         while (endIndex < recentsCount) {
-            TaskRecord cur = get(endIndex);
+            TaskRecord cur = mTasks.get(endIndex);
             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: looking at next chain @"
                     + endIndex + " " + cur);
             if (cur == top) {
@@ -487,8 +1313,8 @@
             for (int i=topIndex; i<=endIndex; i++) {
                 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: moving affiliated " + task
                         + " from " + i + " to " + (i-topIndex));
-                TaskRecord cur = remove(i);
-                add(i - topIndex, cur);
+                TaskRecord cur = mTasks.remove(i);
+                mTasks.add(i - topIndex, cur);
             }
             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: done moving tasks  " +  topIndex
                     + " to " + endIndex);
@@ -499,301 +1325,87 @@
         return false;
     }
 
-    final void addLocked(TaskRecord task) {
-        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
-                || task.mNextAffiliateTaskId != INVALID_TASK_ID
-                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
-
-        int recentsCount = size();
-        // Quick case: never add voice sessions.
-        // TODO: VI what about if it's just an activity?
-        // Probably nothing to do here
-        if (task.voiceSession != null) {
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                    "addRecent: not adding voice interaction " + task);
-            return;
-        }
-        // Another quick case: check if the top-most recent task is the same.
-        if (!isAffiliated && recentsCount > 0 && get(0) == task) {
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: already at top: " + task);
-            return;
-        }
-        // Another quick case: check if this is part of a set of affiliated
-        // tasks that are at the top.
-        if (isAffiliated && recentsCount > 0 && task.inRecents
-                && task.mAffiliatedTaskId == get(0).mAffiliatedTaskId) {
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: affiliated " + get(0)
-                    + " at top when adding " + task);
+    void dump(PrintWriter pw, boolean dumpAll, String dumpPackage) {
+        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
+        if (mTasks.isEmpty()) {
             return;
         }
 
-        boolean needAffiliationFix = false;
+        final MutableBoolean printedAnything = new MutableBoolean(false);
+        final MutableBoolean printedHeader = new MutableBoolean(false);
+        final int size = mTasks.size();
+        for (int i = 0; i < size; i++) {
+            final TaskRecord tr = mTasks.get(i);
+            if (dumpPackage != null && (tr.realActivity == null ||
+                    !dumpPackage.equals(tr.realActivity.getPackageName()))) {
+                continue;
+            }
 
-        // Slightly less quick case: the task is already in recents, so all we need
-        // to do is move it.
-        if (task.inRecents) {
-            int taskIndex = indexOf(task);
-            if (taskIndex >= 0) {
-                if (!isAffiliated || MOVE_AFFILIATED_TASKS_TO_FRONT) {
-                    // Simple case: this is not an affiliated task, so we just move it to the front.
-                    remove(taskIndex);
-                    add(0, task);
-                    notifyTaskPersisterLocked(task, false);
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: moving to top " + task
-                            + " from " + taskIndex);
-                    return;
-                } else {
-                    // More complicated: need to keep all affiliated tasks together.
-                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
-                        // All went well.
-                        return;
-                    }
-
-                    // Uh oh...  something bad in the affiliation chain, try to rebuild
-                    // everything and then go through our general path of adding a new task.
-                    needAffiliationFix = true;
-                }
-            } else {
-                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
-                needAffiliationFix = true;
+            if (!printedHeader.value) {
+                pw.println("  Recent tasks:");
+                printedHeader.value = true;
+                printedAnything.value = true;
+            }
+            pw.print("  * Recent #"); pw.print(i); pw.print(": ");
+            pw.println(tr);
+            if (dumpAll) {
+                tr.dump(pw, "    ");
             }
         }
 
-        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: trimming tasks for " + task);
-        trimForTaskLocked(task, true);
-
-        recentsCount = size();
-        final int maxRecents = ActivityManager.getMaxRecentTasksStatic();
-        while (recentsCount >= maxRecents) {
-            final TaskRecord tr = remove(recentsCount - 1);
-            tr.removedFromRecents();
-            recentsCount--;
-        }
-        task.inRecents = true;
-        if (!isAffiliated || needAffiliationFix) {
-            // If this is a simple non-affiliated task, or we had some failure trying to
-            // handle it as part of an affilated task, then just place it at the top.
-            add(0, task);
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: adding " + task);
-        } else if (isAffiliated) {
-            // If this is a new affiliated task, then move all of the affiliated tasks
-            // to the front and insert this new one.
-            TaskRecord other = task.mNextAffiliate;
-            if (other == null) {
-                other = task.mPrevAffiliate;
-            }
-            if (other != null) {
-                int otherIndex = indexOf(other);
-                if (otherIndex >= 0) {
-                    // Insert new task at appropriate location.
-                    int taskIndex;
-                    if (other == task.mNextAffiliate) {
-                        // We found the index of our next affiliation, which is who is
-                        // before us in the list, so add after that point.
-                        taskIndex = otherIndex+1;
-                    } else {
-                        // We found the index of our previous affiliation, which is who is
-                        // after us in the list, so add at their position.
-                        taskIndex = otherIndex;
-                    }
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                            "addRecent: new affiliated task added at " + taskIndex + ": " + task);
-                    add(taskIndex, task);
-
-                    // Now move everything to the front.
-                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
-                        // All went well.
-                        return;
-                    }
-
-                    // Uh oh...  something bad in the affiliation chain, try to rebuild
-                    // everything and then go through our general path of adding a new task.
-                    needAffiliationFix = true;
-                } else {
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                            "addRecent: couldn't find other affiliation " + other);
-                    needAffiliationFix = true;
-                }
-            } else {
-                if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                        "addRecent: adding affiliated task without next/prev:" + task);
-                needAffiliationFix = true;
-            }
-        }
-
-        if (needAffiliationFix) {
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: regrouping affiliations");
-            cleanupLocked(task.userId);
+        if (!printedAnything.value) {
+            pw.println("  (nothing)");
         }
     }
 
     /**
-     * If needed, remove oldest existing entries in recents that are for the same kind
-     * of task as the given one.
+     * Creates a new RecentTaskInfo from a TaskRecord.
      */
-    int trimForTaskLocked(TaskRecord task, boolean doTrim) {
-        int recentsCount = size();
-        final Intent intent = task.intent;
-        final boolean document = intent != null && intent.isDocument();
-        int maxRecents = task.maxRecents - 1;
-        final ActivityStack stack = task.getStack();
-        for (int i = 0; i < recentsCount; i++) {
-            final TaskRecord tr = get(i);
-            final ActivityStack trStack = tr.getStack();
-            if (task != tr) {
-                if (stack != null && trStack != null && stack != trStack) {
-                    continue;
-                }
-                if (task.userId != tr.userId) {
-                    continue;
-                }
-                final Intent trIntent = tr.intent;
-                final boolean sameAffinity =
-                        task.affinity != null && task.affinity.equals(tr.affinity);
-                final boolean sameIntentFilter = intent != null && intent.filterEquals(trIntent);
-                boolean multiTasksAllowed = false;
-                final int flags = intent.getFlags();
-                if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0
-                        && (flags & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
-                    multiTasksAllowed = true;
-                }
-                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
-                final boolean bothDocuments = document && trIsDocument;
-                if (!sameAffinity && !sameIntentFilter && !bothDocuments) {
-                    continue;
-                }
+    static ActivityManager.RecentTaskInfo createRecentTaskInfo(TaskRecord tr) {
+        // Update the task description to reflect any changes in the task stack
+        tr.updateTaskDescription();
 
-                if (bothDocuments) {
-                    // Do these documents belong to the same activity?
-                    final boolean sameActivity = task.realActivity != null
-                            && tr.realActivity != null
-                            && task.realActivity.equals(tr.realActivity);
-                    // If the document is open in another app or is not the same
-                    // document, we don't need to trim it.
-                    if (!sameActivity) {
-                        continue;
-                    // Otherwise only trim if we are over our max recents for this task
-                    } else if (maxRecents > 0) {
-                        --maxRecents;
-                        if (!doTrim || !sameIntentFilter || multiTasksAllowed) {
-                            // We don't want to trim if we are not over the max allowed entries and
-                            // the caller doesn't want us to trim, the tasks are not of the same
-                            // intent filter, or multiple entries fot the task is allowed.
-                            continue;
-                        }
-                    }
-                    // Hit the maximum number of documents for this task. Fall through
-                    // and remove this document from recents.
-                } else if (document || trIsDocument) {
-                    // Only one of these is a document. Not the droid we're looking for.
-                    continue;
-                }
-            }
+        // Compose the recent task info
+        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
+        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
+        rti.persistentId = tr.taskId;
+        rti.baseIntent = new Intent(tr.getBaseIntent());
+        rti.origActivity = tr.origActivity;
+        rti.realActivity = tr.realActivity;
+        rti.description = tr.lastDescription;
+        rti.stackId = tr.getStackId();
+        rti.userId = tr.userId;
+        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
+        rti.lastActiveTime = tr.lastActiveTime;
+        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
+        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
+        rti.numActivities = 0;
+        if (tr.mBounds != null) {
+            rti.bounds = new Rect(tr.mBounds);
+        }
+        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreenWindowingMode();
+        rti.resizeMode = tr.mResizeMode;
+        rti.configuration.setTo(tr.getConfiguration());
 
-            if (!doTrim) {
-                // If the caller is not actually asking for a trim, just tell them we reached
-                // a point where the trim would happen.
-                return i;
-            }
+        ActivityRecord base = null;
+        ActivityRecord top = null;
+        ActivityRecord tmp;
 
-            // Either task and tr are the same or, their affinities match or their intents match
-            // and neither of them is a document, or they are documents using the same activity
-            // and their maxRecents has been reached.
-            remove(i);
-            if (task != tr) {
-                tr.removedFromRecents();
+        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
+            tmp = tr.mActivities.get(i);
+            if (tmp.finishing) {
+                continue;
             }
-            i--;
-            recentsCount--;
-            if (task.intent == null) {
-                // If the new recent task we are adding is not fully
-                // specified, then replace it with the existing recent task.
-                task = tr;
+            base = tmp;
+            if (top == null || (top.state == ActivityState.INITIALIZING)) {
+                top = base;
             }
-            notifyTaskPersisterLocked(tr, false);
+            rti.numActivities++;
         }
 
-        return -1;
-    }
+        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
+        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
 
-    // Sort by taskId
-    private static Comparator<TaskRecord> sTaskRecordComparator = new Comparator<TaskRecord>() {
-        @Override
-        public int compare(TaskRecord lhs, TaskRecord rhs) {
-            return rhs.taskId - lhs.taskId;
-        }
-    };
-
-    // Extract the affiliates of the chain containing recent at index start.
-    private int processNextAffiliateChainLocked(int start) {
-        final TaskRecord startTask = get(start);
-        final int affiliateId = startTask.mAffiliatedTaskId;
-
-        // Quick identification of isolated tasks. I.e. those not launched behind.
-        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
-                startTask.mNextAffiliate == null) {
-            // There is still a slim chance that there are other tasks that point to this task
-            // and that the chain is so messed up that this task no longer points to them but
-            // the gain of this optimization outweighs the risk.
-            startTask.inRecents = true;
-            return start + 1;
-        }
-
-        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
-        mTmpRecents.clear();
-        for (int i = size() - 1; i >= start; --i) {
-            final TaskRecord task = get(i);
-            if (task.mAffiliatedTaskId == affiliateId) {
-                remove(i);
-                mTmpRecents.add(task);
-            }
-        }
-
-        // Sort them all by taskId. That is the order they were create in and that order will
-        // always be correct.
-        Collections.sort(mTmpRecents, sTaskRecordComparator);
-
-        // Go through and fix up the linked list.
-        // The first one is the end of the chain and has no next.
-        final TaskRecord first = mTmpRecents.get(0);
-        first.inRecents = true;
-        if (first.mNextAffiliate != null) {
-            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
-            first.setNextAffiliate(null);
-            notifyTaskPersisterLocked(first, false);
-        }
-        // Everything in the middle is doubly linked from next to prev.
-        final int tmpSize = mTmpRecents.size();
-        for (int i = 0; i < tmpSize - 1; ++i) {
-            final TaskRecord next = mTmpRecents.get(i);
-            final TaskRecord prev = mTmpRecents.get(i + 1);
-            if (next.mPrevAffiliate != prev) {
-                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
-                        " setting prev=" + prev);
-                next.setPrevAffiliate(prev);
-                notifyTaskPersisterLocked(next, false);
-            }
-            if (prev.mNextAffiliate != next) {
-                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
-                        " setting next=" + next);
-                prev.setNextAffiliate(next);
-                notifyTaskPersisterLocked(prev, false);
-            }
-            prev.inRecents = true;
-        }
-        // The last one is the beginning of the list and has no prev.
-        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
-        if (last.mPrevAffiliate != null) {
-            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
-            last.setPrevAffiliate(null);
-            notifyTaskPersisterLocked(last, false);
-        }
-
-        // Insert the group back into mRecentTasks at start.
-        addAll(start, mTmpRecents);
-        mTmpRecents.clear();
-
-        // Let the caller know where we left off.
-        return start + tmpSize;
+        return rti;
     }
 }
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index ac85e6b..16995e5 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -33,6 +33,7 @@
 import android.content.pm.ServiceInfo;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -517,14 +518,27 @@
                             } catch (PackageManager.NameNotFoundException e) {
                             }
                         }
-                        if (localForegroundNoti.getSmallIcon() == null
-                                || nm.getNotificationChannel(localPackageName, appUid,
+                        if (nm.getNotificationChannel(localPackageName, appUid,
                                 localForegroundNoti.getChannelId()) == null) {
+                            int targetSdkVersion = Build.VERSION_CODES.O_MR1;
+                            try {
+                                final ApplicationInfo applicationInfo =
+                                        ams.mContext.getPackageManager().getApplicationInfoAsUser(
+                                                appInfo.packageName, 0, userId);
+                                targetSdkVersion = applicationInfo.targetSdkVersion;
+                            } catch (PackageManager.NameNotFoundException e) {
+                            }
+                            if (targetSdkVersion >= Build.VERSION_CODES.O_MR1) {
+                                throw new RuntimeException(
+                                        "invalid channel for service notification: "
+                                                + foregroundNoti);
+                            }
+                        }
+                        if (localForegroundNoti.getSmallIcon() == null) {
                             // Notifications whose icon is 0 are defined to not show
                             // a notification, silently ignoring it.  We don't want to
                             // just ignore it, we want to prevent the service from
                             // being foreground.
-                            // Also every notification needs a channel.
                             throw new RuntimeException("invalid service notification: "
                                     + foregroundNoti);
                         }
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 61994b5..2689d6a 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -567,7 +567,7 @@
         SparseArray<SparseBooleanArray> changedTaskIdsPerUser = new SparseArray<>();
         synchronized (mService) {
             for (int userId : mRecentTasks.usersWithRecentsLoadedLocked()) {
-                SparseBooleanArray taskIdsToSave = mRecentTasks.mPersistedTaskIds.get(userId);
+                SparseBooleanArray taskIdsToSave = mRecentTasks.getTaskIdsForUser(userId);
                 SparseBooleanArray persistedIdsInFile = mTaskIdsInFile.get(userId);
                 if (persistedIdsInFile != null && persistedIdsInFile.equals(taskIdsToSave)) {
                     continue;
@@ -640,7 +640,7 @@
         @Override
         public void run() {
             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-            ArraySet<Integer> persistentTaskIds = new ArraySet<Integer>();
+            ArraySet<Integer> persistentTaskIds = new ArraySet<>();
             while (true) {
                 // We can't lock mService while holding TaskPersister.this, but we don't want to
                 // call removeObsoleteFiles every time through the loop, only the last time before
@@ -654,20 +654,7 @@
                     persistentTaskIds.clear();
                     synchronized (mService) {
                         if (DEBUG) Slog.d(TAG, "mRecents=" + mRecentTasks);
-                        for (int taskNdx = mRecentTasks.size() - 1; taskNdx >= 0; --taskNdx) {
-                            final TaskRecord task = mRecentTasks.get(taskNdx);
-                            if (DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task +
-                                    " persistable=" + task.isPersistable);
-                            final ActivityStack stack = task.getStack();
-                            if ((task.isPersistable || task.inRecents)
-                                    && (stack == null || !stack.isHomeOrRecentsStack())) {
-                                if (DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task);
-                                persistentTaskIds.add(task.taskId);
-                            } else {
-                                if (DEBUG) Slog.d(TAG,
-                                        "omitting from persistentTaskIds task=" + task);
-                            }
-                        }
+                        mRecentTasks.getPersistableTaskIds(persistentTaskIds);
                         mService.mWindowManager.removeObsoleteTaskFiles(persistentTaskIds,
                                 mRecentTasks.usersWithRecentsLoadedLocked());
                     }
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 0d8df79..0bc30cf 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -18,10 +18,7 @@
 
 import static android.app.ActivityManager.RESIZE_MODE_FORCED;
 import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -31,6 +28,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
 import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
@@ -45,7 +43,6 @@
 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
-import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
 import static android.view.Display.DEFAULT_DISPLAY;
@@ -86,7 +83,6 @@
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManager.StackId;
 import android.app.ActivityManager.TaskDescription;
 import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityOptions;
@@ -102,6 +98,7 @@
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -155,8 +152,6 @@
     private static final String ATTR_EFFECTIVE_UID = "effective_uid";
     @Deprecated
     private static final String ATTR_TASKTYPE = "task_type";
-    private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
-    private static final String ATTR_LASTACTIVETIME = "last_active_time";
     private static final String ATTR_LASTDESCRIPTION = "last_description";
     private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
     private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
@@ -168,7 +163,6 @@
     private static final String ATTR_CALLING_PACKAGE = "calling_package";
     private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
     private static final String ATTR_RESIZE_MODE = "resize_mode";
-    private static final String ATTR_PRIVILEGED = "privileged";
     private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
     private static final String ATTR_MIN_WIDTH = "min_width";
     private static final String ATTR_MIN_HEIGHT = "min_height";
@@ -212,9 +206,10 @@
     ComponentName realActivity; // The actual activity component that started the task.
     boolean realActivitySuspended; // True if the actual activity component that started the
                                    // task is suspended.
-    long firstActiveTime;   // First time this task was active.
-    long lastActiveTime;    // Last time this task was active, including sleep.
     boolean inRecents;      // Actually in the recents list?
+    long lastActiveTime;    // Last time this task was active in the current device session,
+                            // including sleep. This time is initialized to the elapsed time when
+                            // restored from disk.
     boolean isAvailable;    // Is the activity available to be launched?
     boolean rootWasReset;   // True if the intent at the root of the task had
                             // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
@@ -237,10 +232,6 @@
             // of the root activity.
     boolean mTemporarilyUnresizable; // Separate flag from mResizeMode used to suppress resize
                                      // changes on a temporary basis.
-    private int mLockTaskMode;  // Which tasklock mode to launch this task in. One of
-                                // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
-    private boolean mPrivileged;    // The root activity application of this task holds
-                                    // privileged permissions.
 
     /** Can't be put in lockTask mode. */
     final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
@@ -339,6 +330,7 @@
                 TaskPersister.IMAGE_EXTENSION;
         userId = UserHandle.getUserId(info.applicationInfo.uid);
         taskId = _taskId;
+        lastActiveTime = SystemClock.elapsedRealtime();
         mAffiliatedTaskId = _taskId;
         voiceSession = _voiceSession;
         voiceInteractor = _voiceInteractor;
@@ -359,6 +351,7 @@
                 TaskPersister.IMAGE_EXTENSION;
         userId = UserHandle.getUserId(info.applicationInfo.uid);
         taskId = _taskId;
+        lastActiveTime = SystemClock.elapsedRealtime();
         mAffiliatedTaskId = _taskId;
         voiceSession = null;
         voiceInteractor = null;
@@ -385,12 +378,11 @@
             ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
             boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
             int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
-            long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
-            boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
-            int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
-            int callingUid, String callingPackage, int resizeMode, boolean supportsPictureInPicture,
-            boolean privileged, boolean _realActivitySuspended, boolean userSetupComplete,
-            int minWidth, int minHeight) {
+            long lastTimeMoved, boolean neverRelinquishIdentity,
+            TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
+            int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
+            int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
+            boolean userSetupComplete, int minWidth, int minHeight) {
         mService = service;
         mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
                 TaskPersister.IMAGE_EXTENSION;
@@ -412,8 +404,7 @@
         userId = _userId;
         mUserSetupComplete = userSetupComplete;
         effectiveUid = _effectiveUid;
-        firstActiveTime = _firstActiveTime;
-        lastActiveTime = _lastActiveTime;
+        lastActiveTime = SystemClock.elapsedRealtime();
         lastDescription = _lastDescription;
         mActivities = activities;
         mLastTimeMoved = lastTimeMoved;
@@ -427,7 +418,6 @@
         mCallingPackage = callingPackage;
         mResizeMode = resizeMode;
         mSupportsPictureInPicture = supportsPictureInPicture;
-        mPrivileged = privileged;
         mMinWidth = minWidth;
         mMinHeight = minHeight;
         mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
@@ -520,7 +510,7 @@
             // All we can do for now is update the bounds so it can be used when the task is
             // added to window manager.
             updateOverrideConfiguration(bounds);
-            if (getStackId() != FREEFORM_WORKSPACE_STACK_ID) {
+            if (!inFreeformWindowingMode()) {
                 // re-restore the task so it can have the proper stack association.
                 mService.mStackSupervisor.restoreRecentTaskLocked(this, null);
             }
@@ -616,8 +606,7 @@
      * @return whether the task was reparented
      */
     // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
-    // re-parenting the task. Can only be done when we are no longer using static stack Ids like
-    /** {@link ActivityManager.StackId#FULLSCREEN_WORKSPACE_STACK_ID} */
+    // re-parenting the task. Can only be done when we are no longer using static stack Ids.
     boolean reparent(ActivityStack preferredStack, int position,
             @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
             boolean schedulePictureInPictureModeChange, String reason) {
@@ -630,12 +619,12 @@
             return false;
         }
 
-        final int sourceStackId = getStackId();
-        final int stackId = toStack.getStackId();
+        final int toStackWindowingMode = toStack.getWindowingMode();
         final ActivityRecord topActivity = getTopActivity();
 
-        final boolean mightReplaceWindow = StackId.replaceWindowsOnTaskMove(sourceStackId, stackId)
-                && topActivity != null;
+        final boolean mightReplaceWindow =
+                replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode)
+                        && topActivity != null;
         if (mightReplaceWindow) {
             // We are about to relaunch the activity because its configuration changed due to
             // being maximized, i.e. size change. The activity will first remove the old window
@@ -660,7 +649,7 @@
             // In some cases the focused stack isn't the front stack. E.g. pinned stack.
             // Whenever we are moving the top activity from the front stack we want to make sure to
             // move the stack to the front.
-            final boolean wasFront = r != null && supervisor.isFrontStackOnDisplay(sourceStack)
+            final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
                     && (sourceStack.topRunningActivityLocked() == r);
 
             // Adjust the position for the new parent stack as needed.
@@ -707,10 +696,10 @@
             toStack.prepareFreezingTaskBounds();
 
             // Make sure the task has the appropriate bounds/size for the stack it is in.
-            final int toStackWindowingMode = toStack.getWindowingMode();
             final boolean toStackSplitScreenPrimary =
                     toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-            if (stackId == FULLSCREEN_WORKSPACE_STACK_ID
+            if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
+                    || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
                     && !Objects.equals(mBounds, toStack.mBounds)) {
                 kept = resize(toStack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow,
                         deferResume);
@@ -749,9 +738,9 @@
         }
 
         // TODO: Handle incorrect request to move before the actual move, not after.
-        final boolean inSplitScreenMode = supervisor.getDefaultDisplay().hasSplitScreenStack();
+        final boolean inSplitScreenMode = supervisor.getDefaultDisplay().hasSplitScreenPrimaryStack();
         supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
-                DEFAULT_DISPLAY, stackId);
+                DEFAULT_DISPLAY, toStack);
 
         boolean successful = (preferredStack == toStack);
         if (successful && toStack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
@@ -761,6 +750,18 @@
         return successful;
     }
 
+    /**
+     * Returns true if the windows of tasks being moved to the target stack from the source
+     * stack should be replaced, meaning that window manager will keep the old window around
+     * until the new is ready.
+     * @hide
+     */
+    private static boolean replaceWindowsOnTaskMove(
+            int sourceWindowingMode, int targetWindowingMode) {
+        return sourceWindowingMode == WINDOWING_MODE_FREEFORM
+                || targetWindowingMode == WINDOWING_MODE_FREEFORM;
+    }
+
     void cancelWindowTransition() {
         mWindowContainerController.cancelWindowTransition();
     }
@@ -780,14 +781,11 @@
     }
 
     void touchActiveTime() {
-        lastActiveTime = System.currentTimeMillis();
-        if (firstActiveTime == 0) {
-            firstActiveTime = lastActiveTime;
-        }
+        lastActiveTime = SystemClock.elapsedRealtime();
     }
 
     long getInactiveDuration() {
-        return System.currentTimeMillis() - lastActiveTime;
+        return SystemClock.elapsedRealtime() - lastActiveTime;
     }
 
     /** Sets the original intent, and the calling uid and package. */
@@ -795,6 +793,7 @@
         mCallingUid = r.launchedFromUid;
         mCallingPackage = r.launchedFromPackage;
         setIntent(r.intent, r.info);
+        setLockTaskAuth(r);
     }
 
     /** Sets the original intent, _without_ updating the calling uid or package. */
@@ -878,14 +877,6 @@
         }
         mResizeMode = info.resizeMode;
         mSupportsPictureInPicture = info.supportsPictureInPicture();
-        mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
-        mLockTaskMode = info.lockTaskLaunchMode;
-        if (!mPrivileged && (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
-                || mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
-            // Non-priv apps are not allowed to use always or never, fall back to default
-            mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
-        }
-        setLockTaskAuth();
     }
 
     /** Sets the original minimal width and height. */
@@ -1263,7 +1254,7 @@
             mService.notifyTaskPersisterLocked(this, false);
         }
 
-        if (getStackId() == PINNED_STACK_ID) {
+        if (inPinnedWindowingMode()) {
             // We normally notify listeners of task stack changes on pause, however pinned stack
             // activities are normally in the paused state so no notification will be sent there
             // before the activity is removed. We send it here so instead.
@@ -1422,8 +1413,17 @@
     }
 
     void setLockTaskAuth() {
+        setLockTaskAuth(getRootActivity());
+    }
+
+    private void setLockTaskAuth(@Nullable ActivityRecord r) {
+        if (r == null) {
+            mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
+            return;
+        }
+
         final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
-        switch (mLockTaskMode) {
+        switch (r.lockTaskLaunchMode) {
             case LOCK_TASK_LAUNCH_MODE_DEFAULT:
                 mLockTaskAuth = mService.mLockTaskController.isPackageWhitelisted(userId, pkg)
                         ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
@@ -1493,7 +1493,7 @@
      * @return True if the requested bounds are okay for a resizing request.
      */
     private boolean canResizeToBounds(Rect bounds) {
-        if (bounds == null || getStackId() != FREEFORM_WORKSPACE_STACK_ID) {
+        if (bounds == null || !inFreeformWindowingMode()) {
             // Note: If not on the freeform workspace, we ignore the bounds.
             return true;
         }
@@ -1647,8 +1647,6 @@
         out.attribute(null, ATTR_USERID, String.valueOf(userId));
         out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
         out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
-        out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
-        out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
         out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
         out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
         if (lastDescription != null) {
@@ -1666,7 +1664,6 @@
         out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
         out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
                 String.valueOf(mSupportsPictureInPicture));
-        out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
         if (mLastNonFullscreenBounds != null) {
             out.attribute(
                     null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
@@ -1721,8 +1718,6 @@
         boolean userSetupComplete = true;
         int effectiveUid = -1;
         String lastDescription = null;
-        long firstActiveTime = -1;
-        long lastActiveTime = -1;
         long lastTimeOnTop = 0;
         boolean neverRelinquishIdentity = true;
         int taskId = INVALID_TASK_ID;
@@ -1736,7 +1731,6 @@
         String callingPackage = "";
         int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
         boolean supportsPictureInPicture = false;
-        boolean privileged = false;
         Rect bounds = null;
         int minWidth = INVALID_MIN_SIZE;
         int minHeight = INVALID_MIN_SIZE;
@@ -1774,10 +1768,6 @@
                 effectiveUid = Integer.parseInt(attrValue);
             } else if (ATTR_TASKTYPE.equals(attrName)) {
                 taskType = Integer.parseInt(attrValue);
-            } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
-                firstActiveTime = Long.parseLong(attrValue);
-            } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
-                lastActiveTime = Long.parseLong(attrValue);
             } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
                 lastDescription = attrValue;
             } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
@@ -1802,8 +1792,6 @@
                 resizeMode = Integer.parseInt(attrValue);
             } else if (ATTR_SUPPORTS_PICTURE_IN_PICTURE.equals(attrName)) {
                 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
-            } else if (ATTR_PRIVILEGED.equals(attrName)) {
-                privileged = Boolean.parseBoolean(attrValue);
             } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
                 bounds = Rect.unflattenFromString(attrValue);
             } else if (ATTR_MIN_WIDTH.equals(attrName)) {
@@ -1888,10 +1876,10 @@
         final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
                 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
                 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
-                activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
-                taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
-                callingUid, callingPackage, resizeMode, supportsPictureInPicture, privileged,
-                realActivitySuspended, userSetupComplete, minWidth, minHeight);
+                activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
+                taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
+                callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
+                userSetupComplete, minWidth, minHeight);
         task.updateOverrideConfiguration(bounds);
 
         for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
@@ -1911,7 +1899,7 @@
         // If the task has no requested minimal size, we'd like to enforce a minimal size
         // so that the user can not render the task too small to manipulate. We don't need
         // to do this for the pinned stack as the bounds are controlled by the system.
-        if (getStackId() != PINNED_STACK_ID) {
+        if (!inPinnedWindowingMode()) {
             if (minWidth == INVALID_MIN_SIZE) {
                 minWidth = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
             }
@@ -2085,7 +2073,7 @@
             return;
         }
 
-        if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+        if (inStack.inFreeformWindowingMode()) {
             if (!isResizeable()) {
                 throw new IllegalArgumentException("Can not position non-resizeable task="
                         + this + " in stack=" + inStack);
@@ -2220,7 +2208,6 @@
                 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
                 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
                 pw.print(" isResizeable=" + isResizeable());
-                pw.print(" firstActiveTime=" + firstActiveTime);
                 pw.print(" lastActiveTime=" + lastActiveTime);
                 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
     }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 055c9f6..5a29594 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -631,7 +631,6 @@
     void finishUserStopping(final int userId, final UserState uss) {
         // On to the next.
         final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
-        shutdownIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
         // This is the result receiver for the final shutdown broadcast.
         final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
             @Override
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 6506cf7..4943173 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -184,11 +184,15 @@
         }
     }
 
+    private static final int FLAGS_FOR_SILENCE_OVERRIDE =
+            AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY |
+            AudioAttributes.FLAG_BYPASS_MUTE;
+
     private void checkVolumeForPrivilegedAlarm(AudioPlaybackConfiguration apc, int event) {
         if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED ||
                 apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
-            if ((apc.getAudioAttributes().getAllFlags() &
-                    AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0 &&
+            if ((apc.getAudioAttributes().getAllFlags() & FLAGS_FOR_SILENCE_OVERRIDE)
+                        == FLAGS_FOR_SILENCE_OVERRIDE  &&
                     apc.getAudioAttributes().getUsage() == AudioAttributes.USAGE_ALARM &&
                     mContext.checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE,
                             apc.getClientPid(), apc.getClientUid()) ==
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 5583e86..d7cd81f 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -1371,6 +1371,7 @@
                     sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
                 }
             }
+            mUpstreamNetworkMonitor.setCurrentUpstream((ns != null) ? ns.network : null);
             setUpstreamNetwork(ns);
         }
 
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index c5f7528..b35ed75 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -95,7 +95,10 @@
     private NetworkCallback mDefaultNetworkCallback;
     private NetworkCallback mMobileNetworkCallback;
     private boolean mDunRequired;
-    private Network mCurrentDefault;
+    // The current system default network (not really used yet).
+    private Network mDefaultInternetNetwork;
+    // The current upstream network used for tethering.
+    private Network mTetheringUpstreamNetwork;
 
     public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, SharedLog log, int what) {
         mContext = ctx;
@@ -130,10 +133,12 @@
 
         releaseCallback(mDefaultNetworkCallback);
         mDefaultNetworkCallback = null;
+        mDefaultInternetNetwork = null;
 
         releaseCallback(mListenAllCallback);
         mListenAllCallback = null;
 
+        mTetheringUpstreamNetwork = null;
         mNetworkMap.clear();
     }
 
@@ -207,7 +212,7 @@
                 break;
             default:
                 /* If we've found an active upstream connection that's not DUN/HIPRI
-                 * we should stop any outstanding DUN/HIPRI start requests.
+                 * we should stop any outstanding DUN/HIPRI requests.
                  *
                  * If we found NONE we don't want to do this as we want any previous
                  * requests to keep trying to bring up something we can use.
@@ -219,6 +224,10 @@
         return typeStatePair.ns;
     }
 
+    public void setCurrentUpstream(Network upstream) {
+        mTetheringUpstreamNetwork = upstream;
+    }
+
     public Set<IpPrefix> getLocalPrefixes() {
         return (Set<IpPrefix>) mLocalPrefixes.clone();
     }
@@ -250,7 +259,7 @@
                     // These request*() calls can be deleted post oag/339444.
                     return;
                 }
-                mCurrentDefault = network;
+                mDefaultInternetNetwork = network;
                 break;
 
             case CALLBACK_MOBILE_REQUEST:
@@ -302,6 +311,13 @@
                     network, newNc));
         }
 
+        // Log changes in upstream network signal strength, if available.
+        if (network.equals(mTetheringUpstreamNetwork) && newNc.hasSignalStrength()) {
+            final int newSignal = newNc.getSignalStrength();
+            final String prevSignal = getSignalStrength(prev.networkCapabilities);
+            mLog.logf("upstream network signal strength: %s -> %s", prevSignal, newSignal);
+        }
+
         mNetworkMap.put(network, new NetworkState(
                 null, prev.linkProperties, newNc, network, null, null));
         // TODO: If sufficient information is available to select a more
@@ -330,9 +346,21 @@
         notifyTarget(EVENT_ON_LINKPROPERTIES, network);
     }
 
+    private void handleSuspended(int callbackType, Network network) {
+        if (callbackType != CALLBACK_LISTEN_ALL) return;
+        if (!network.equals(mTetheringUpstreamNetwork)) return;
+        mLog.log("SUSPENDED current upstream: " + network);
+    }
+
+    private void handleResumed(int callbackType, Network network) {
+        if (callbackType != CALLBACK_LISTEN_ALL) return;
+        if (!network.equals(mTetheringUpstreamNetwork)) return;
+        mLog.log("RESUMED current upstream: " + network);
+    }
+
     private void handleLost(int callbackType, Network network) {
         if (callbackType == CALLBACK_TRACK_DEFAULT) {
-            mCurrentDefault = null;
+            mDefaultInternetNetwork = null;
             // Receiving onLost() for a default network does not necessarily
             // mean the network is gone.  We wait for a separate notification
             // on either the LISTEN_ALL or MOBILE_REQUEST callbacks before
@@ -401,8 +429,15 @@
             recomputeLocalPrefixes();
         }
 
-        // TODO: Handle onNetworkSuspended();
-        // TODO: Handle onNetworkResumed();
+        @Override
+        public void onNetworkSuspended(Network network) {
+            handleSuspended(mCallbackType, network);
+        }
+
+        @Override
+        public void onNetworkResumed(Network network) {
+            handleResumed(mCallbackType, network);
+        }
 
         @Override
         public void onLost(Network network) {
@@ -467,4 +502,9 @@
 
         return prefixSet;
     }
+
+    private static String getSignalStrength(NetworkCapabilities nc) {
+        if (nc == null || !nc.hasSignalStrength()) return "unknown";
+        return Integer.toString(nc.getSignalStrength());
+    }
 }
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 9aabdab..9a6e609 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -29,6 +29,7 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.text.format.DateUtils;
 import android.util.EventLog;
 import android.util.MathUtils;
@@ -304,6 +305,7 @@
     }
 
     private void handleLightSensorEvent(long time, float lux) {
+        Trace.traceCounter(Trace.TRACE_TAG_POWER, "ALS", (int) lux);
         mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
 
         if (mAmbientLightRingBuffer.size() == 0) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index f8e5836..f930b52 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -683,8 +683,8 @@
         // Configure auto-brightness.
         boolean autoBrightnessEnabled = false;
         if (mAutomaticBrightnessController != null) {
-            final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
-                    && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
+            final boolean autoBrightnessEnabledInDoze =
+                    mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
             autoBrightnessEnabled = mPowerRequest.useAutoBrightness
                     && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
                     && brightness < 0;
@@ -726,8 +726,7 @@
         }
 
         // Use default brightness when dozing unless overridden.
-        if (brightness < 0 && (state == Display.STATE_DOZE
-                || state == Display.STATE_DOZE_SUSPEND)) {
+        if (brightness < 0 && Display.isDozeState(state)) {
             brightness = mScreenBrightnessDozeConfig;
         }
 
@@ -777,7 +776,6 @@
         // Skip the animation when the screen is off or suspended or transition to/from VR.
         if (!mPendingScreenOff) {
             if (mSkipScreenOnBrightnessRamp) {
-
                 if (state == Display.STATE_ON) {
                     if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
                         mInitialAutoBrightness = brightness;
@@ -794,15 +792,25 @@
                 }
             }
 
-            boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
-            if ((state == Display.STATE_ON
-                    && mSkipRampState == RAMP_STATE_SKIP_NONE
-                    || state == Display.STATE_DOZE && !mBrightnessBucketsInDozeConfig)
-                    && !wasOrWillBeInVr) {
+            final boolean wasOrWillBeInVr =
+                    (state == Display.STATE_VR || oldState == Display.STATE_VR);
+            final boolean initialRampSkip =
+                    state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE;
+            // While dozing, sometimes the brightness is split into buckets. Rather than animating
+            // through the buckets, which is unlikely to be smooth in the first place, just jump
+            // right to the suggested brightness.
+            final boolean hasBrightnessBuckets =
+                    Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
+            // If the color fade is totally covering the screen then we can change the backlight
+            // level without it being a noticeable jump since any actual content isn't yet visible.
+            final boolean isDisplayContentVisible =
+                    mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
+            if (initialRampSkip || hasBrightnessBuckets
+                    || wasOrWillBeInVr || !isDisplayContentVisible) {
+                animateScreenBrightness(brightness, 0);
+            } else {
                 animateScreenBrightness(brightness,
                         slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
-            } else {
-                animateScreenBrightness(brightness, 0);
             }
         }
 
@@ -925,6 +933,7 @@
             }
 
             if (!reportOnly) {
+                Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
                 mPowerState.setScreenState(state);
                 // Tell battery stats about the transition.
                 try {
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 0aa6a90..e41c17d 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -417,7 +417,11 @@
     // stops output right at 600m/s, depriving this of the information of a device that reaches
     // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
     private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
-    private boolean mItarSpeedLimitExceeded = false;
+
+    // TODO: improve comment
+    // Volatile to ensure that potentially near-concurrent outputs from HAL
+    // react to this value change promptly
+    private volatile boolean mItarSpeedLimitExceeded = false;
 
     // GNSS Metrics
     private GnssMetrics mGnssMetrics;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 0b11479..664d2f9 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -784,6 +784,14 @@
                 mService.enforcePhoneStatePermission(pid, uid);
             }
             mFlags = flags;
+            if ((flags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    mService.setGlobalPrioritySession(MediaSessionRecord.this);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
             mHandler.post(MessageHandler.MSG_UPDATE_SESSION_STATE);
         }
 
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index b9a2d18..aa65244 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -178,17 +178,6 @@
                 return;
             }
             if ((record.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
-                if (mGlobalPrioritySession != record) {
-                    Log.d(TAG, "Global priority session is changed from " + mGlobalPrioritySession
-                            + " to " + record);
-                    mGlobalPrioritySession = record;
-                    if (user != null && user.mPriorityStack.contains(record)) {
-                        // Handle the global priority session separately.
-                        // Otherwise, it will be the media button session even after it becomes
-                        // inactive because it has been the lastly played media app.
-                        user.mPriorityStack.removeSession(record);
-                    }
-                }
                 if (DEBUG_KEY_EVENT) {
                     Log.d(TAG, "Global priority session is updated, active=" + record.isActive());
                 }
@@ -204,10 +193,27 @@
         }
     }
 
+    public void setGlobalPrioritySession(MediaSessionRecord record) {
+        synchronized (mLock) {
+            FullUserRecord user = getFullUserRecordLocked(record.getUserId());
+            if (mGlobalPrioritySession != record) {
+                Log.d(TAG, "Global priority session is changed from " + mGlobalPrioritySession
+                        + " to " + record);
+                mGlobalPrioritySession = record;
+                if (user != null && user.mPriorityStack.contains(record)) {
+                    // Handle the global priority session separately.
+                    // Otherwise, it can be the media button session regardless of the active state
+                    // because it or other system components might have been the lastly played media
+                    // app.
+                    user.mPriorityStack.removeSession(record);
+                }
+            }
+        }
+    }
+
     private List<MediaSessionRecord> getActiveSessionsLocked(int userId) {
-        List<MediaSessionRecord> records;
+        List<MediaSessionRecord> records = new ArrayList<>();
         if (userId == UserHandle.USER_ALL) {
-            records = new ArrayList<>();
             int size = mUserRecords.size();
             for (int i = 0; i < size; i++) {
                 records.addAll(mUserRecords.valueAt(i).mPriorityStack.getActiveSessions(userId));
@@ -216,9 +222,9 @@
             FullUserRecord user = getFullUserRecordLocked(userId);
             if (user == null) {
                 Log.w(TAG, "getSessions failed. Unknown user " + userId);
-                return new ArrayList<>();
+                return records;
             }
-            records = user.mPriorityStack.getActiveSessions(userId);
+            records.addAll(user.mPriorityStack.getActiveSessions(userId));
         }
 
         // Return global priority session at the first whenever it's asked.
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 14cd055..168f070 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -282,6 +282,7 @@
     private WindowManagerInternal mWindowManagerInternal;
     private AlarmManager mAlarmManager;
     private ICompanionDeviceManager mCompanionManager;
+    private AccessibilityManager mAccessibilityManager;
 
     final IBinder mForegroundToken = new Binder();
     private WorkerHandler mHandler;
@@ -1221,6 +1222,12 @@
         mUsageStats = us;
     }
 
+    @VisibleForTesting
+    void setAccessibilityManager(AccessibilityManager am) {
+        mAccessibilityManager = am;
+    }
+
+
     // TODO: All tests should use this init instead of the one-off setters above.
     @VisibleForTesting
     void init(Looper looper, IPackageManager packageManager,
@@ -1235,6 +1242,8 @@
                 Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
                 DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE);
 
+        mAccessibilityManager =
+                (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
         mAm = ActivityManager.getService();
         mPackageManager = packageManager;
         mPackageManagerClient = packageManagerClient;
@@ -4117,13 +4126,16 @@
         // These are set inside the conditional if the notification is allowed to make noise.
         boolean hasValidVibrate = false;
         boolean hasValidSound = false;
+        boolean sentAccessibilityEvent = false;
+        // If the notification will appear in the status bar, it should send an accessibility
+        // event
+        if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
+            sendAccessibilityEvent(notification, record.sbn.getPackageName());
+            sentAccessibilityEvent = true;
+        }
 
         if (aboveThreshold && isNotificationForCurrentUser(record)) {
-            // If the notification will appear in the status bar, it should send an accessibility
-            // event
-            if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
-                sendAccessibilityEvent(notification, record.sbn.getPackageName());
-            }
+
             if (mSystemReady && mAudioManager != null) {
                 Uri soundUri = record.getSound();
                 hasValidSound = soundUri != null && !Uri.EMPTY.equals(soundUri);
@@ -4141,6 +4153,10 @@
 
                 boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
                 if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
+                    if (!sentAccessibilityEvent) {
+                        sendAccessibilityEvent(notification, record.sbn.getPackageName());
+                        sentAccessibilityEvent = true;
+                    }
                     if (DBG) Slog.v(TAG, "Interrupting!");
                     if (hasValidSound) {
                         mSoundNotificationKey = key;
@@ -4661,8 +4677,7 @@
     }
 
     void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
-        AccessibilityManager manager = AccessibilityManager.getInstance(getContext());
-        if (!manager.isEnabled()) {
+        if (!mAccessibilityManager.isEnabled()) {
             return;
         }
 
@@ -4676,7 +4691,7 @@
             event.getText().add(tickerText);
         }
 
-        manager.sendAccessibilityEvent(event);
+        mAccessibilityManager.sendAccessibilityEvent(event);
     }
 
     /**
diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java
index a7a2743..abf2900 100644
--- a/services/core/java/com/android/server/notification/ZenModeFiltering.java
+++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java
@@ -117,15 +117,19 @@
                 ZenLog.traceIntercepted(record, "alarmsOnly");
                 return true;
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
-                if (isAlarm(record)) {
-                    // Alarms are always priority
-                    return false;
-                }
                 // allow user-prioritized packages through in priority mode
                 if (record.getPackagePriority() == Notification.PRIORITY_MAX) {
                     ZenLog.traceNotIntercepted(record, "priorityApp");
                     return false;
                 }
+
+                if (isAlarm(record)) {
+                    if (!config.allowAlarms) {
+                        ZenLog.traceIntercepted(record, "!allowAlarms");
+                        return true;
+                    }
+                    return false;
+                }
                 if (isCall(record)) {
                     if (config.allowRepeatCallers
                             && REPEAT_CALLERS.isRepeat(mContext, extras(record))) {
@@ -159,6 +163,15 @@
                     }
                     return false;
                 }
+                AudioAttributes aa = record.getAudioAttributes();
+                if (aa != null && AudioAttributes.SUPPRESSIBLE_USAGES.get(aa.getUsage()) ==
+                        AudioAttributes.SUPPRESSIBLE_MEDIA_SYSTEM_OTHER) {
+                    if (!config.allowMediaSystemOther) {
+                        ZenLog.traceIntercepted(record, "!allowMediaSystemOther");
+                        return true;
+                    }
+                    return false;
+                }
                 ZenLog.traceIntercepted(record, "!priority");
                 return true;
             default:
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 9fcc67d..710684f 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -59,6 +59,7 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.server.LocalServices;
 
@@ -87,7 +88,7 @@
     private final Context mContext;
     private final H mHandler;
     private final SettingsObserver mSettingsObserver;
-    private final AppOpsManager mAppOps;
+    @VisibleForTesting protected final AppOpsManager mAppOps;
     protected ZenModeConfig mDefaultConfig;
     private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
     private final ZenModeFiltering mFiltering;
@@ -102,9 +103,9 @@
     private final String SCHEDULED_DEFAULT_RULE_1 = "SCHEDULED_DEFAULT_RULE_1";
     private final String SCHEDULED_DEFAULT_RULE_2 = "SCHEDULED_DEFAULT_RULE_2";
 
-    private int mZenMode;
+    @VisibleForTesting protected int mZenMode;
     private int mUser = UserHandle.USER_SYSTEM;
-    protected ZenModeConfig mConfig;
+    @VisibleForTesting protected ZenModeConfig mConfig;
     private AudioManagerInternal mAudioManager;
     protected PackageManager mPm;
     private long mSuppressedEffects;
@@ -595,8 +596,9 @@
             pw.println(config);
             return;
         }
-        pw.printf("allow(calls=%b,callsFrom=%s,repeatCallers=%b,messages=%b,messagesFrom=%s,"
+        pw.printf("allow(alarms=%b,media=%bcalls=%b,callsFrom=%s,repeatCallers=%b,messages=%b,messagesFrom=%s,"
                 + "events=%b,reminders=%b,whenScreenOff=%b,whenScreenOn=%b)\n",
+                config.allowAlarms, config.allowMediaSystemOther,
                 config.allowCalls, ZenModeConfig.sourceToString(config.allowCallsFrom),
                 config.allowRepeatCallers, config.allowMessages,
                 ZenModeConfig.sourceToString(config.allowMessagesFrom),
@@ -813,7 +815,8 @@
         }
     }
 
-    private void applyRestrictions() {
+    @VisibleForTesting
+    protected void applyRestrictions() {
         final boolean zen = mZenMode != Global.ZEN_MODE_OFF;
 
         // notification restrictions
@@ -822,6 +825,10 @@
         // call restrictions
         final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers
                 || (mSuppressedEffects & SUPPRESSED_EFFECT_CALLS) != 0;
+        // alarm restrictions
+        final boolean muteAlarms = zen && !mConfig.allowAlarms;
+        // alarm restrictions
+        final boolean muteMediaAndSystemSounds = zen && !mConfig.allowMediaSystemOther;
         // total silence restrictions
         final boolean muteEverything = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
 
@@ -833,13 +840,18 @@
                 applyRestrictions(muteNotifications || muteEverything, usage);
             } else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_CALL) {
                 applyRestrictions(muteCalls || muteEverything, usage);
+            } else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_ALARM) {
+                applyRestrictions(muteAlarms || muteEverything, usage);
+            } else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_MEDIA_SYSTEM_OTHER) {
+                applyRestrictions(muteMediaAndSystemSounds || muteEverything, usage);
             } else {
                 applyRestrictions(muteEverything, usage);
             }
         }
     }
 
-    private void applyRestrictions(boolean mute, int usage) {
+    @VisibleForTesting
+    protected void applyRestrictions(boolean mute, int usage) {
         final String[] exceptionPackages = null; // none (for now)
         mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, usage,
                 mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 4a5ce12..b06b583 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -30,12 +30,10 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ILauncherApps;
 import android.content.pm.IOnAppsChangedListener;
-import android.content.pm.IPackageManager;
 import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
@@ -64,7 +62,6 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -89,10 +86,14 @@
     static class BroadcastCookie {
         public final UserHandle user;
         public final String packageName;
+        public final int callingUid;
+        public final int callingPid;
 
-        BroadcastCookie(UserHandle userHandle, String packageName) {
+        BroadcastCookie(UserHandle userHandle, String packageName, int callingPid, int callingUid) {
             this.user = userHandle;
             this.packageName = packageName;
+            this.callingUid = callingUid;
+            this.callingPid = callingPid;
         }
     }
 
@@ -127,6 +128,11 @@
             return getCallingUid();
         }
 
+        @VisibleForTesting
+        int injectBinderCallingPid() {
+            return getCallingPid();
+        }
+
         final int injectCallingUserId() {
             return UserHandle.getUserId(injectBinderCallingUid());
         }
@@ -166,7 +172,7 @@
                 }
                 mListeners.unregister(listener);
                 mListeners.register(listener, new BroadcastCookie(UserHandle.of(getCallingUserId()),
-                        callingPackage));
+                        callingPackage, injectBinderCallingPid(), injectBinderCallingUid()));
             }
         }
 
@@ -438,7 +444,7 @@
         private void ensureShortcutPermission(@NonNull String callingPackage) {
             verifyCallingPackage(callingPackage);
             if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
-                    callingPackage)) {
+                    callingPackage, injectBinderCallingPid(), injectBinderCallingUid())) {
                 throw new SecurityException("Caller can't access shortcut information");
             }
         }
@@ -461,7 +467,8 @@
             return new ParceledListSlice<>((List<ShortcutInfo>)
                     mShortcutServiceInternal.getShortcuts(getCallingUserId(),
                             callingPackage, changedSince, packageName, shortcutIds,
-                            componentName, flags, targetUser.getIdentifier()));
+                            componentName, flags, targetUser.getIdentifier(),
+                            injectBinderCallingPid(), injectBinderCallingUid()));
         }
 
         @Override
@@ -514,7 +521,7 @@
         public boolean hasShortcutHostPermission(String callingPackage) {
             verifyCallingPackage(callingPackage);
             return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
-                    callingPackage);
+                    callingPackage, injectBinderCallingPid(), injectBinderCallingUid());
         }
 
         @Override
@@ -536,7 +543,8 @@
             }
 
             final Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
-                    getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId);
+                    getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId,
+                    injectBinderCallingPid(), injectBinderCallingUid());
             if (intents == null || intents.length == 0) {
                 return false;
             }
@@ -901,7 +909,8 @@
 
                         // Make sure the caller has the permission.
                         if (!mShortcutServiceInternal.hasShortcutHostPermission(
-                                launcherUserId, cookie.packageName)) {
+                                launcherUserId, cookie.packageName,
+                                cookie.callingPid, cookie.callingUid)) {
                             continue;
                         }
                         // Each launcher has a different set of pinned shortcuts, so we need to do a
@@ -914,8 +923,8 @@
                                         /* changedSince= */ 0, packageName, /* shortcutIds=*/ null,
                                         /* component= */ null,
                                         ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
-                                        | ShortcutQuery.FLAG_GET_ALL_KINDS
-                                        , userId);
+                                        | ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED
+                                        , userId, cookie.callingPid, cookie.callingUid);
                         try {
                             listener.onShortcutChanged(user, packageName,
                                     new ParceledListSlice<>(list));
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 8ebeeae..cf0ffbb 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -236,9 +236,10 @@
      */
     @GuardedBy("mInstallLock")
     private int dexOptPath(PackageParser.Package pkg, String path, String isa,
-            String compilerFilter, boolean profileUpdated, String sharedLibrariesPath,
+            String compilerFilter, boolean profileUpdated, String classLoaderContext,
             int dexoptFlags, int uid, CompilerStats.PackageStats packageStats, boolean downgrade) {
-        int dexoptNeeded = getDexoptNeeded(path, isa, compilerFilter, profileUpdated, downgrade);
+        int dexoptNeeded = getDexoptNeeded(path, isa, compilerFilter, classLoaderContext,
+                profileUpdated, downgrade);
         if (Math.abs(dexoptNeeded) == DexFile.NO_DEXOPT_NEEDED) {
             return DEX_OPT_SKIPPED;
         }
@@ -251,8 +252,8 @@
         Log.i(TAG, "Running dexopt (dexoptNeeded=" + dexoptNeeded + ") on: " + path
                 + " pkg=" + pkg.applicationInfo.packageName + " isa=" + isa
                 + " dexoptFlags=" + printDexoptFlags(dexoptFlags)
-                + " target-filter=" + compilerFilter + " oatDir=" + oatDir
-                + " sharedLibraries=" + sharedLibrariesPath);
+                + " targetFilter=" + compilerFilter + " oatDir=" + oatDir
+                + " classLoaderContext=" + classLoaderContext);
 
         try {
             long startTime = System.currentTimeMillis();
@@ -261,7 +262,7 @@
             // installd only uses downgrade flag for secondary dex files and ignores it for
             // primary dex files.
             mInstaller.dexopt(path, uid, pkg.packageName, isa, dexoptNeeded, oatDir, dexoptFlags,
-                    compilerFilter, pkg.volumeUuid, sharedLibrariesPath, pkg.applicationInfo.seInfo,
+                    compilerFilter, pkg.volumeUuid, classLoaderContext, pkg.applicationInfo.seInfo,
                     false /* downgrade*/);
 
             if (packageStats != null) {
@@ -508,11 +509,11 @@
      * configuration (isa, compiler filter, profile).
      */
     private int getDexoptNeeded(String path, String isa, String compilerFilter,
-            boolean newProfile, boolean downgrade) {
+            String classLoaderContext, boolean newProfile, boolean downgrade) {
         int dexoptNeeded;
         try {
-            dexoptNeeded = DexFile.getDexOptNeeded(path, isa, compilerFilter, newProfile,
-                    downgrade);
+            dexoptNeeded = DexFile.getDexOptNeeded(path, isa, compilerFilter, classLoaderContext,
+                    newProfile, downgrade);
         } catch (IOException ioe) {
             Slog.w(TAG, "IOException reading apk: " + path, ioe);
             return DEX_OPT_FAILED;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7d1a647..d2f2426 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -398,7 +398,7 @@
     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
     private static final boolean DEBUG_BACKUP = false;
     private static final boolean DEBUG_INSTALL = false;
-    private static final boolean DEBUG_REMOVE = false;
+    public static final boolean DEBUG_REMOVE = false;
     private static final boolean DEBUG_BROADCASTS = false;
     private static final boolean DEBUG_SHOW_INFO = false;
     private static final boolean DEBUG_PACKAGE_INFO = false;
@@ -406,7 +406,7 @@
     public static final boolean DEBUG_PACKAGE_SCANNING = false;
     private static final boolean DEBUG_VERIFY = false;
     private static final boolean DEBUG_FILTERS = false;
-    private static final boolean DEBUG_PERMISSIONS = false;
+    public static final boolean DEBUG_PERMISSIONS = false;
     private static final boolean DEBUG_SHARED_LIBRARIES = false;
     private static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
 
@@ -954,9 +954,6 @@
     final SparseArray<PackageVerificationState> mPendingVerification
             = new SparseArray<PackageVerificationState>();
 
-    /** Set of packages associated with each app op permission. */
-    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
-
     final PackageInstallerService mInstallerService;
 
     private final PackageDexOptimizer mPackageDexOptimizer;
@@ -2881,7 +2878,7 @@
                         + mSdkVersion + "; regranting permissions for internal storage");
                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
             }
-            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
+            updatePermissionsLocked(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
             ver.sdkVersion = mSdkVersion;
 
             // If this is the first boot or an update from pre-M, and it is a normal
@@ -3368,7 +3365,9 @@
     @Override
     public boolean isUpgrade() {
         // allow instant applications
-        return mIsUpgrade;
+        // The system property allows testing ota flow when upgraded to the same image.
+        return mIsUpgrade || SystemProperties.getBoolean(
+                "persist.pm.mock-upgrade", false /* default */);
     }
 
     private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
@@ -5182,7 +5181,7 @@
                 final PermissionsState permissionsState = settingBase.getPermissionsState();
                 if (permissionsState.hasPermission(permName, userId)) {
                     if (isUidInstantApp) {
-                        if (mPermissionManager.isPermissionInstant(permName)) {
+                        if (mSettings.mPermissions.isPermissionInstant(permName)) {
                             return PackageManager.PERMISSION_GRANTED;
                         }
                     } else {
@@ -5251,8 +5250,8 @@
         }
     }
 
-    boolean addPermission(PermissionInfo info, final boolean async) {
-        return mPermissionManager.addPermission(
+    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
+        return mPermissionManager.addDynamicPermission(
                 info, async, getCallingUid(), new PermissionCallback() {
                     @Override
                     public void onPermissionChanged() {
@@ -5268,20 +5267,20 @@
     @Override
     public boolean addPermission(PermissionInfo info) {
         synchronized (mPackages) {
-            return addPermission(info, false);
+            return addDynamicPermission(info, false);
         }
     }
 
     @Override
     public boolean addPermissionAsync(PermissionInfo info) {
         synchronized (mPackages) {
-            return addPermission(info, true);
+            return addDynamicPermission(info, true);
         }
     }
 
     @Override
     public void removePermission(String permName) {
-        mPermissionManager.removePermission(permName, getCallingUid(), mPermissionCallback);
+        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
     }
 
     @Override
@@ -5942,17 +5941,8 @@
     }
 
     @Override
-    public String[] getAppOpPermissionPackages(String permissionName) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return null;
-        }
-        synchronized (mPackages) {
-            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
-            if (pkgs == null) {
-                return null;
-            }
-            return pkgs.toArray(new String[pkgs.size()]);
-        }
+    public String[] getAppOpPermissionPackages(String permName) {
+        return mPermissionManager.getAppOpPermissionPackages(permName);
     }
 
     @Override
@@ -10346,7 +10336,7 @@
                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
                                     + pkg.packageName);
                             // SIDE EFFECTS; updates permissions system state; move elsewhere
-                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
+                            mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
                         }
                     }
                 }
@@ -11194,54 +11184,13 @@
                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
             }
 
-            N = pkg.permissions.size();
-            r = null;
-            for (i=0; i<N; i++) {
-                PackageParser.Permission p = pkg.permissions.get(i);
 
-                // Dont allow ephemeral apps to define new permissions.
-                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
-                    Slog.w(TAG, "Permission " + p.info.name + " from package "
-                            + p.info.packageName
-                            + " ignored: instant apps cannot define new permissions.");
-                    continue;
-                }
-
-                // Assume by default that we did not install this permission into the system.
-                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
-
-                // Now that permission groups have a special meaning, we ignore permission
-                // groups for legacy apps to prevent unexpected behavior. In particular,
-                // permissions for one app being granted to someone just because they happen
-                // to be in a group defined by another app (before this had no implications).
-                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
-                    p.group = mPermissionGroups.get(p.info.group);
-                    // Warn for a permission in an unknown group.
-                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
-                        Slog.i(TAG, "Permission " + p.info.name + " from package "
-                                + p.info.packageName + " in an unknown group " + p.info.group);
-                    }
-                }
-
-                // TODO Move to PermissionManager once mPermissionTrees moves there.
-//                        p.tree ? mSettings.mPermissionTrees
-//                                : mSettings.mPermissions;
-//                final BasePermission bp = BasePermission.createOrUpdate(
-//                        permissionMap.get(p.info.name), p, pkg, mSettings.mPermissionTrees, chatty);
-//                permissionMap.put(p.info.name, bp);
-                if (p.tree) {
-                    final ArrayMap<String, BasePermission> permissionMap =
-                            mSettings.mPermissionTrees;
-                    final BasePermission bp = BasePermission.createOrUpdate(
-                            permissionMap.get(p.info.name), p, pkg, mSettings.mPermissionTrees,
-                            chatty);
-                    permissionMap.put(p.info.name, bp);
-                } else {
-                    final BasePermission bp = BasePermission.createOrUpdate(
-                            (BasePermission) mPermissionManager.getPermissionTEMP(p.info.name),
-                            p, pkg, mSettings.mPermissionTrees, chatty);
-                    mPermissionManager.putPermissionTEMP(p.info.name, bp);
-                }
+            // Dont allow ephemeral apps to define new permissions.
+            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
+                Slog.w(TAG, "Permissions from package " + pkg.packageName
+                        + " ignored: instant apps cannot define new permissions.");
+            } else {
+                mPermissionManager.addAllPermissions(pkg, chatty);
             }
 
             N = pkg.instrumentation.size();
@@ -11967,53 +11916,7 @@
             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
         }
 
-        N = pkg.permissions.size();
-        r = null;
-        for (i=0; i<N; i++) {
-            PackageParser.Permission p = pkg.permissions.get(i);
-            BasePermission bp = (BasePermission) mPermissionManager.getPermissionTEMP(p.info.name);
-            if (bp == null) {
-                bp = mSettings.mPermissionTrees.get(p.info.name);
-            }
-            if (bp != null && bp.isPermission(p)) {
-                bp.setPermission(null);
-                if (DEBUG_REMOVE && chatty) {
-                    if (r == null) {
-                        r = new StringBuilder(256);
-                    } else {
-                        r.append(' ');
-                    }
-                    r.append(p.info.name);
-                }
-            }
-            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
-                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
-                if (appOpPkgs != null) {
-                    appOpPkgs.remove(pkg.packageName);
-                }
-            }
-        }
-        if (r != null) {
-            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
-        }
-
-        N = pkg.requestedPermissions.size();
-        r = null;
-        for (i=0; i<N; i++) {
-            String perm = pkg.requestedPermissions.get(i);
-            if (mPermissionManager.isPermissionAppOp(perm)) {
-                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
-                if (appOpPkgs != null) {
-                    appOpPkgs.remove(pkg.packageName);
-                    if (appOpPkgs.isEmpty()) {
-                        mAppOpPermissionPackages.remove(perm);
-                    }
-                }
-            }
-        }
-        if (r != null) {
-            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
-        }
+        mPermissionManager.removeAllPermissions(pkg, chatty);
 
         N = pkg.instrumentation.size();
         r = null;
@@ -12074,18 +11977,9 @@
         }
     }
 
-    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
-        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
-            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
-    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
-    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
+    public static final int UPDATE_PERMISSIONS_ALL = 1<<0;
+    public static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
+    public static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
 
     private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
         // Update the parent permissions
@@ -12101,10 +11995,10 @@
     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
             int flags) {
         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
-        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
+        updatePermissionsLocked(changingPkg, pkgInfo, volumeUuid, flags);
     }
 
-    private void updatePermissionsLPw(String changingPkg,
+    private void updatePermissionsLocked(String changingPkg,
             PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
         // TODO: Most of the methods exposing BasePermission internals [source package name,
         // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
@@ -12116,55 +12010,11 @@
         // normal permissions. Today, we need two separate loops because these BasePermission
         // objects are stored separately.
         // Make sure there are no dangling permission trees.
-        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
-        while (it.hasNext()) {
-            final BasePermission bp = it.next();
-            if (bp.getSourcePackageSetting() == null) {
-                // We may not yet have parsed the package, so just see if
-                // we still know about its settings.
-                bp.setSourcePackageSetting(mSettings.mPackages.get(bp.getSourcePackageName()));
-            }
-            if (bp.getSourcePackageSetting() == null) {
-                Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
-                        + " from package " + bp.getSourcePackageName());
-                it.remove();
-            } else if (changingPkg != null && changingPkg.equals(bp.getSourcePackageName())) {
-                if (pkgInfo == null || !hasPermission(pkgInfo, bp.getName())) {
-                    Slog.i(TAG, "Removing old permission tree: " + bp.getName()
-                            + " from package " + bp.getSourcePackageName());
-                    flags |= UPDATE_PERMISSIONS_ALL;
-                    it.remove();
-                }
-            }
-        }
+        flags = mPermissionManager.updatePermissionTrees(changingPkg, pkgInfo, flags);
 
         // Make sure all dynamic permissions have been assigned to a package,
         // and make sure there are no dangling permissions.
-        final Iterator<BasePermission> permissionIter =
-                mPermissionManager.getPermissionIteratorTEMP();
-        while (permissionIter.hasNext()) {
-            final BasePermission bp = permissionIter.next();
-            if (bp.isDynamic()) {
-                bp.updateDynamicPermission(mSettings.mPermissionTrees);
-            }
-            if (bp.getSourcePackageSetting() == null) {
-                // We may not yet have parsed the package, so just see if
-                // we still know about its settings.
-                bp.setSourcePackageSetting(mSettings.mPackages.get(bp.getSourcePackageName()));
-            }
-            if (bp.getSourcePackageSetting() == null) {
-                Slog.w(TAG, "Removing dangling permission: " + bp.getName()
-                        + " from package " + bp.getSourcePackageName());
-                permissionIter.remove();
-            } else if (changingPkg != null && changingPkg.equals(bp.getSourcePackageName())) {
-                if (pkgInfo == null || !hasPermission(pkgInfo, bp.getName())) {
-                    Slog.i(TAG, "Removing old permission: " + bp.getName()
-                            + " from package " + bp.getSourcePackageName());
-                    flags |= UPDATE_PERMISSIONS_ALL;
-                    permissionIter.remove();
-                }
-            }
-        }
+        flags = mPermissionManager.updatePermissions(changingPkg, pkgInfo, flags);
 
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
         // Now update the permissions for all packages, in particular
@@ -12286,12 +12136,7 @@
 
             // Keep track of app op permissions.
             if (bp.isAppOp()) {
-                ArraySet<String> pkgs = mAppOpPermissionPackages.get(perm);
-                if (pkgs == null) {
-                    pkgs = new ArraySet<>();
-                    mAppOpPermissionPackages.put(perm, pkgs);
-                }
-                pkgs.add(pkg.packageName);
+                mSettings.addAppOpPackage(perm, pkg.packageName);
             }
 
             if (bp.isNormal()) {
@@ -21238,7 +21083,7 @@
         // permissions, ensure permissions are updated. Beware of dragons if you
         // try optimizing this.
         synchronized (mPackages) {
-            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL,
+            updatePermissionsLocked(null, null, StorageManager.UUID_PRIVATE_INTERNAL,
                     UPDATE_PERMISSIONS_ALL);
         }
 
@@ -21289,9 +21134,8 @@
         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
 
         if (mPrivappPermissionsViolations != null) {
-            Slog.wtf(TAG,"Signature|privileged permissions not in "
+            throw new IllegalStateException("Signature|privileged permissions not in "
                     + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
-            mPrivappPermissionsViolations = null;
         }
     }
 
@@ -21784,22 +21628,6 @@
 
             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
                 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
-                if (packageName == null && permissionNames == null) {
-                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
-                        if (iperm == 0) {
-                            if (dumpState.onTitlePrinted())
-                                pw.println();
-                            pw.println("AppOp Permissions:");
-                        }
-                        pw.print("  AppOp Permission ");
-                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
-                        pw.println(":");
-                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
-                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
-                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
-                        }
-                    }
-                }
             }
 
             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
@@ -22065,7 +21893,7 @@
     }
 
     private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
-        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
+        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
         ipw.println();
         ipw.println("Dexopt state:");
         ipw.increaseIndent();
@@ -22092,7 +21920,7 @@
     }
 
     private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
-        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
+        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
         ipw.println();
         ipw.println("Compiler stats:");
         ipw.increaseIndent();
@@ -22303,7 +22131,7 @@
                         + mSdkVersion + "; regranting permissions for " + volumeUuid);
                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
             }
-            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
+            updatePermissionsLocked(null, null, volumeUuid, updateFlags);
 
             // Yay, everything is now upgraded
             ver.forceCurrent();
@@ -23311,15 +23139,15 @@
     void onNewUserCreated(final int userId) {
         synchronized(mPackages) {
             mDefaultPermissionPolicy.grantDefaultPermissions(mPackages.values(), userId);
-        }
-        // If permission review for legacy apps is required, we represent
-        // dagerous permissions for such apps as always granted runtime
-        // permissions to keep per user flag state whether review is needed.
-        // Hence, if a new user is added we have to propagate dangerous
-        // permission grants for these legacy apps.
-        if (mPermissionReviewRequired) {
-            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
-                    | UPDATE_PERMISSIONS_REPLACE_ALL);
+            // If permission review for legacy apps is required, we represent
+            // dagerous permissions for such apps as always granted runtime
+            // permissions to keep per user flag state whether review is needed.
+            // Hence, if a new user is added we have to propagate dangerous
+            // permission grants for these legacy apps.
+            if (mPermissionReviewRequired) {
+                updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
+                        | UPDATE_PERMISSIONS_REPLACE_ALL);
+            }
         }
     }
 
@@ -23763,12 +23591,12 @@
         }
 
         @Override
-        public Object enforcePermissionTreeTEMP(String permName, int callingUid) {
+        public PackageParser.PermissionGroup getPermissionGroupTEMP(String groupName) {
             synchronized (mPackages) {
-                return BasePermission.enforcePermissionTreeLP(
-                        mSettings.mPermissionTrees, permName, callingUid);
+                return mPermissionGroups.get(groupName);
             }
         }
+
         @Override
         public boolean isInstantApp(String packageName, int userId) {
             return PackageManagerService.this.isInstantApp(packageName, userId);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 0084411..56595c9 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -378,10 +378,6 @@
     private final ArrayMap<Long, Integer> mKeySetRefs =
             new ArrayMap<Long, Integer>();
 
-    // Mapping from permission tree names to info about them.
-    final ArrayMap<String, BasePermission> mPermissionTrees =
-            new ArrayMap<String, BasePermission>();
-
     // Packages that have been uninstalled and still need their external
     // storage data deleted.
     final ArrayList<PackageCleanItem> mPackagesToBeCleaned = new ArrayList<PackageCleanItem>();
@@ -416,7 +412,7 @@
 
     public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages);
     /** Settings and other information about permissions */
-    private final PermissionSettings mPermissions;
+    final PermissionSettings mPermissions;
 
     Settings(PermissionSettings permissions, Object lock) {
         this(Environment.getDataDirectory(), permissions, lock);
@@ -622,6 +618,10 @@
         return null;
     }
 
+    void addAppOpPackage(String permName, String packageName) {
+        mPermissions.addAppOpPackage(permName, packageName);
+    }
+
     SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
         SharedUserSetting s = mSharedUsers.get(name);
         if (s != null) {
@@ -666,13 +666,6 @@
     }
 
     /**
-     * Transfers ownership of permissions from one package to another.
-     */
-    void transferPermissionsLPw(String origPackageName, String newPackageName) {
-        mPermissions.transferPermissions(origPackageName, newPackageName, mPermissionTrees);
-    }
-
-    /**
      * Creates a new {@code PackageSetting} object.
      * Use this method instead of the constructor to ensure a settings object is created
      * with the correct base.
@@ -2496,9 +2489,7 @@
             }
 
             serializer.startTag(null, "permission-trees");
-            for (BasePermission bp : mPermissionTrees.values()) {
-                writePermissionLPr(serializer, bp);
-            }
+            mPermissions.writePermissionTrees(serializer);
             serializer.endTag(null, "permission-trees");
 
             serializer.startTag(null, "permissions");
@@ -3042,7 +3033,7 @@
                 } else if (tagName.equals("permissions")) {
                     mPermissions.readPermissions(parser);
                 } else if (tagName.equals("permission-trees")) {
-                    PermissionSettings.readPermissions(mPermissionTrees, parser);
+                    mPermissions.readPermissionTrees(parser);
                 } else if (tagName.equals("shared-user")) {
                     readSharedUserLPw(parser);
                 } else if (tagName.equals("preferred-packages")) {
diff --git a/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java b/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java
index 4f5d156..815f885 100644
--- a/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java
+++ b/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java
@@ -21,6 +21,8 @@
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.drawable.Icon;
+import android.os.StrictMode;
+import android.os.StrictMode.ThreadPolicy;
 import android.os.SystemClock;
 import android.util.Log;
 import android.util.Slog;
@@ -165,7 +167,13 @@
 
         // Compress it and enqueue to the requests.
         final byte[] bytes;
+        final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
         try {
+            // compress() triggers a slow call, but in this case it's needed to save RAM and also
+            // the target bitmap is of an icon size, so let's just permit it.
+            StrictMode.setThreadPolicy(new ThreadPolicy.Builder(oldPolicy)
+                    .permitCustomSlowCalls()
+                    .build());
             final Bitmap shrunk = mService.shrinkBitmap(original, maxDimension);
             try {
                 try (final ByteArrayOutputStream out = new ByteArrayOutputStream(64 * 1024)) {
@@ -184,6 +192,8 @@
         } catch (IOException | RuntimeException | OutOfMemoryError e) {
             Slog.wtf(ShortcutService.TAG, "Unable to write bitmap to file", e);
             return;
+        } finally {
+            StrictMode.setThreadPolicy(oldPolicy);
         }
 
         shortcut.addFlags(
diff --git a/services/core/java/com/android/server/pm/ShortcutLauncher.java b/services/core/java/com/android/server/pm/ShortcutLauncher.java
index f922ad1..cedf476 100644
--- a/services/core/java/com/android/server/pm/ShortcutLauncher.java
+++ b/services/core/java/com/android/server/pm/ShortcutLauncher.java
@@ -83,11 +83,16 @@
         return mOwnerUserId;
     }
 
+    @Override
+    protected boolean canRestoreAnyVersion() {
+        // Launcher's pinned shortcuts can be restored to an older version.
+        return true;
+    }
+
     /**
      * Called when the new package can't receive the backup, due to signature or version mismatch.
      */
-    @Override
-    protected void onRestoreBlocked() {
+    private void onRestoreBlocked() {
         final ArrayList<PackageWithUser> pinnedPackages =
                 new ArrayList<>(mPinnedShortcuts.keySet());
         mPinnedShortcuts.clear();
@@ -101,15 +106,21 @@
     }
 
     @Override
-    protected void onRestored() {
-        // Nothing to do.
+    protected void onRestored(int restoreBlockReason) {
+        // For launcher, possible reasons here are DISABLED_REASON_SIGNATURE_MISMATCH or
+        // DISABLED_REASON_BACKUP_NOT_SUPPORTED.
+        // DISABLED_REASON_VERSION_LOWER will NOT happen because we don't check version
+        // code for launchers.
+        if (restoreBlockReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
+            onRestoreBlocked();
+        }
     }
 
     /**
      * Pin the given shortcuts, replacing the current pinned ones.
      */
     public void pinShortcuts(@UserIdInt int packageUserId,
-            @NonNull String packageName, @NonNull List<String> ids) {
+            @NonNull String packageName, @NonNull List<String> ids, boolean forPinRequest) {
         final ShortcutPackage packageShortcuts =
                 mShortcutUser.getPackageShortcutsIfExists(packageName);
         if (packageShortcuts == null) {
@@ -124,8 +135,12 @@
         } else {
             final ArraySet<String> prevSet = mPinnedShortcuts.get(pu);
 
-            // Pin shortcuts.  Make sure only pin the ones that were visible to the caller.
-            // i.e. a non-dynamic, pinned shortcut by *other launchers* shouldn't be pinned here.
+            // Actually pin shortcuts.
+            // This logic here is to make sure a launcher cannot pin a shortcut that is floating
+            // (i.e. not dynamic nor manifest but is pinned) and pinned by another launcher.
+            // In this case, technically the shortcut doesn't exist to this launcher, so it can't
+            // pin it.
+            // (Maybe unnecessarily strict...)
 
             final ArraySet<String> newSet = new ArraySet<>();
 
@@ -135,8 +150,10 @@
                 if (si == null) {
                     continue;
                 }
-                if (si.isDynamic() || si.isManifestShortcut()
-                        || (prevSet != null && prevSet.contains(id))) {
+                if (si.isDynamic()
+                        || si.isManifestShortcut()
+                        || (prevSet != null && prevSet.contains(id))
+                        || forPinRequest) {
                     newSet.add(id);
                 }
             }
@@ -155,7 +172,7 @@
     }
 
     /**
-     * Return true if the given shortcut is pinned by this launcher.
+     * Return true if the given shortcut is pinned by this launcher.<code></code>
      */
     public boolean hasPinned(ShortcutInfo shortcut) {
         final ArraySet<String> pinned =
@@ -164,10 +181,10 @@
     }
 
     /**
-     * Additionally pin a shortcut. c.f. {@link #pinShortcuts(int, String, List)}
+     * Additionally pin a shortcut. c.f. {@link #pinShortcuts(int, String, List, boolean)}
      */
     public void addPinnedShortcut(@NonNull String packageName, @UserIdInt int packageUserId,
-            String id) {
+            String id, boolean forPinRequest) {
         final ArraySet<String> pinnedSet = getPinnedShortcutIds(packageName, packageUserId);
         final ArrayList<String> pinnedList;
         if (pinnedSet != null) {
@@ -178,21 +195,21 @@
         }
         pinnedList.add(id);
 
-        pinShortcuts(packageUserId, packageName, pinnedList);
+        pinShortcuts(packageUserId, packageName, pinnedList, forPinRequest);
     }
 
     boolean cleanUpPackage(String packageName, @UserIdInt int packageUserId) {
         return mPinnedShortcuts.remove(PackageWithUser.of(packageUserId, packageName)) != null;
     }
 
-    public void ensureVersionInfo() {
+    public void ensurePackageInfo() {
         final PackageInfo pi = mShortcutUser.mService.getPackageInfoWithSignatures(
                 getPackageName(), getPackageUserId());
         if (pi == null) {
             Slog.w(TAG, "Package not found: " + getPackageName());
             return;
         }
-        getPackageInfo().updateVersionInfo(pi);
+        getPackageInfo().updateFromPackageInfo(pi);
     }
 
     /**
@@ -201,6 +218,10 @@
     @Override
     public void saveToXml(XmlSerializer out, boolean forBackup)
             throws IOException {
+        if (forBackup && !getPackageInfo().isBackupAllowed()) {
+            // If an launcher app doesn't support backup&restore, then nothing to do.
+            return;
+        }
         final int size = mPinnedShortcuts.size();
         if (size == 0) {
             return; // Nothing to write.
@@ -209,7 +230,7 @@
         out.startTag(null, TAG_ROOT);
         ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME, getPackageName());
         ShortcutService.writeAttr(out, ATTR_LAUNCHER_USER_ID, getPackageUserId());
-        getPackageInfo().saveToXml(out);
+        getPackageInfo().saveToXml(out, forBackup);
 
         for (int i = 0; i < size; i++) {
             final PackageWithUser pu = mPinnedShortcuts.keyAt(i);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 6fc1e73..12f490f 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -84,6 +84,7 @@
     private static final String ATTR_DISABLED_MESSAGE = "dmessage";
     private static final String ATTR_DISABLED_MESSAGE_RES_ID = "dmessageid";
     private static final String ATTR_DISABLED_MESSAGE_RES_NAME = "dmessagename";
+    private static final String ATTR_DISABLED_REASON = "disabled-reason";
     private static final String ATTR_INTENT_LEGACY = "intent";
     private static final String ATTR_INTENT_NO_EXTRA = "intent-base";
     private static final String ATTR_RANK = "rank";
@@ -156,13 +157,25 @@
     }
 
     @Override
-    protected void onRestoreBlocked() {
-        // Can't restore due to version/signature mismatch.  Remove all shortcuts.
-        mShortcuts.clear();
+    protected boolean canRestoreAnyVersion() {
+        return false;
     }
 
     @Override
-    protected void onRestored() {
+    protected void onRestored(int restoreBlockReason) {
+        // Shortcuts have been restored.
+        // - Unshadow all shortcuts.
+        // - Set disabled reason.
+        // - Disable if needed.
+        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+            ShortcutInfo si = mShortcuts.valueAt(i);
+            si.clearFlags(ShortcutInfo.FLAG_SHADOW);
+
+            si.setDisabledReason(restoreBlockReason);
+            if (restoreBlockReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
+                si.addFlags(ShortcutInfo.FLAG_DISABLED);
+            }
+        }
         // Because some launchers may not have been restored (e.g. allowBackup=false),
         // we need to re-calculate the pinned shortcuts.
         refreshPinnedFlags();
@@ -176,31 +189,47 @@
         return mShortcuts.get(id);
     }
 
-    private void ensureNotImmutable(@Nullable ShortcutInfo shortcut) {
-        if (shortcut != null && shortcut.isImmutable()) {
+    public boolean isShortcutExistsAndInvisibleToPublisher(String id) {
+        ShortcutInfo si = findShortcutById(id);
+        return si != null && !si.isVisibleToPublisher();
+    }
+
+    public boolean isShortcutExistsAndVisibleToPublisher(String id) {
+        ShortcutInfo si = findShortcutById(id);
+        return si != null && si.isVisibleToPublisher();
+    }
+
+    private void ensureNotImmutable(@Nullable ShortcutInfo shortcut, boolean ignoreInvisible) {
+        if (shortcut != null && shortcut.isImmutable()
+                && (!ignoreInvisible || shortcut.isVisibleToPublisher())) {
             throw new IllegalArgumentException(
                     "Manifest shortcut ID=" + shortcut.getId()
                             + " may not be manipulated via APIs");
         }
     }
 
-    public void ensureNotImmutable(@NonNull String id) {
-        ensureNotImmutable(mShortcuts.get(id));
+    public void ensureNotImmutable(@NonNull String id, boolean ignoreInvisible) {
+        ensureNotImmutable(mShortcuts.get(id), ignoreInvisible);
     }
 
-    public void ensureImmutableShortcutsNotIncludedWithIds(@NonNull List<String> shortcutIds) {
+    public void ensureImmutableShortcutsNotIncludedWithIds(@NonNull List<String> shortcutIds,
+            boolean ignoreInvisible) {
         for (int i = shortcutIds.size() - 1; i >= 0; i--) {
-            ensureNotImmutable(shortcutIds.get(i));
+            ensureNotImmutable(shortcutIds.get(i), ignoreInvisible);
         }
     }
 
-    public void ensureImmutableShortcutsNotIncluded(@NonNull List<ShortcutInfo> shortcuts) {
+    public void ensureImmutableShortcutsNotIncluded(@NonNull List<ShortcutInfo> shortcuts,
+            boolean ignoreInvisible) {
         for (int i = shortcuts.size() - 1; i >= 0; i--) {
-            ensureNotImmutable(shortcuts.get(i).getId());
+            ensureNotImmutable(shortcuts.get(i).getId(), ignoreInvisible);
         }
     }
 
-    private ShortcutInfo deleteShortcutInner(@NonNull String id) {
+    /**
+     * Delete a shortcut by ID. This will *always* remove it even if it's immutable or invisible.
+     */
+    private ShortcutInfo forceDeleteShortcutInner(@NonNull String id) {
         final ShortcutInfo shortcut = mShortcuts.remove(id);
         if (shortcut != null) {
             mShortcutUser.mService.removeIconLocked(shortcut);
@@ -210,10 +239,14 @@
         return shortcut;
     }
 
-    private void addShortcutInner(@NonNull ShortcutInfo newShortcut) {
+    /**
+     * Force replace a shortcut. If there's already a shortcut with the same ID, it'll be removed,
+     * even if it's invisible.
+     */
+    private void forceReplaceShortcutInner(@NonNull ShortcutInfo newShortcut) {
         final ShortcutService s = mShortcutUser.mService;
 
-        deleteShortcutInner(newShortcut.getId());
+        forceDeleteShortcutInner(newShortcut.getId());
 
         // Extract Icon and update the icon res ID and the bitmap path.
         s.saveIconAndFixUpShortcutLocked(newShortcut);
@@ -222,11 +255,12 @@
     }
 
     /**
-     * Add a shortcut, or update one with the same ID, with taking over existing flags.
+     * Add a shortcut. If there's already a one with the same ID, it'll be removed, even if it's
+     * invisible.
      *
      * It checks the max number of dynamic shortcuts.
      */
-    public void addOrUpdateDynamicShortcut(@NonNull ShortcutInfo newShortcut) {
+    public void addOrReplaceDynamicShortcut(@NonNull ShortcutInfo newShortcut) {
 
         Preconditions.checkArgument(newShortcut.isEnabled(),
                 "add/setDynamicShortcuts() cannot publish disabled shortcuts");
@@ -242,7 +276,7 @@
         } else {
             // It's an update case.
             // Make sure the target is updatable. (i.e. should be mutable.)
-            oldShortcut.ensureUpdatableWith(newShortcut);
+            oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false);
 
             wasPinned = oldShortcut.isPinned();
         }
@@ -252,7 +286,7 @@
             newShortcut.addFlags(ShortcutInfo.FLAG_PINNED);
         }
 
-        addShortcutInner(newShortcut);
+        forceReplaceShortcutInner(newShortcut);
     }
 
     /**
@@ -273,7 +307,7 @@
         }
         if (removeList != null) {
             for (int i = removeList.size() - 1; i >= 0; i--) {
-                deleteShortcutInner(removeList.get(i));
+                forceDeleteShortcutInner(removeList.get(i));
             }
         }
     }
@@ -281,13 +315,13 @@
     /**
      * Remove all dynamic shortcuts.
      */
-    public void deleteAllDynamicShortcuts() {
+    public void deleteAllDynamicShortcuts(boolean ignoreInvisible) {
         final long now = mShortcutUser.mService.injectCurrentTimeMillis();
 
         boolean changed = false;
         for (int i = mShortcuts.size() - 1; i >= 0; i--) {
             final ShortcutInfo si = mShortcuts.valueAt(i);
-            if (si.isDynamic()) {
+            if (si.isDynamic() && (!ignoreInvisible || si.isVisibleToPublisher())) {
                 changed = true;
 
                 si.setTimestamp(now);
@@ -307,9 +341,10 @@
      * @return true if it's actually removed because it wasn't pinned, or false if it's still
      * pinned.
      */
-    public boolean deleteDynamicWithId(@NonNull String shortcutId) {
+    public boolean deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) {
         final ShortcutInfo removed = deleteOrDisableWithId(
-                shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false);
+                shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible,
+                ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
         return removed == null;
     }
 
@@ -320,9 +355,11 @@
      * @return true if it's actually removed because it wasn't pinned, or false if it's still
      * pinned.
      */
-    private boolean disableDynamicWithId(@NonNull String shortcutId) {
+    private boolean disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible,
+            int disabledReason) {
         final ShortcutInfo disabled = deleteOrDisableWithId(
-                shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false);
+                shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false, ignoreInvisible,
+                disabledReason);
         return disabled == null;
     }
 
@@ -331,9 +368,10 @@
      * is pinned, it'll remain as a pinned shortcut but will be disabled.
      */
     public void disableWithId(@NonNull String shortcutId, String disabledMessage,
-            int disabledMessageResId, boolean overrideImmutable) {
+            int disabledMessageResId, boolean overrideImmutable, boolean ignoreInvisible,
+            int disabledReason) {
         final ShortcutInfo disabled = deleteOrDisableWithId(shortcutId, /* disable =*/ true,
-                overrideImmutable);
+                overrideImmutable, ignoreInvisible, disabledReason);
 
         if (disabled != null) {
             if (disabledMessage != null) {
@@ -348,14 +386,18 @@
 
     @Nullable
     private ShortcutInfo deleteOrDisableWithId(@NonNull String shortcutId, boolean disable,
-            boolean overrideImmutable) {
+            boolean overrideImmutable, boolean ignoreInvisible, int disabledReason) {
+        Preconditions.checkState(
+                (disable == (disabledReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED)),
+                "disable and disabledReason disagree: " + disable + " vs " + disabledReason);
         final ShortcutInfo oldShortcut = mShortcuts.get(shortcutId);
 
-        if (oldShortcut == null || !oldShortcut.isEnabled()) {
+        if (oldShortcut == null || !oldShortcut.isEnabled()
+                && (ignoreInvisible && !oldShortcut.isVisibleToPublisher())) {
             return null; // Doesn't exist or already disabled.
         }
         if (!overrideImmutable) {
-            ensureNotImmutable(oldShortcut);
+            ensureNotImmutable(oldShortcut, /*ignoreInvisible=*/ true);
         }
         if (oldShortcut.isPinned()) {
 
@@ -363,6 +405,10 @@
             oldShortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_MANIFEST);
             if (disable) {
                 oldShortcut.addFlags(ShortcutInfo.FLAG_DISABLED);
+                // Do not overwrite the disabled reason if one is alreay set.
+                if (oldShortcut.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
+                    oldShortcut.setDisabledReason(disabledReason);
+                }
             }
             oldShortcut.setTimestamp(mShortcutUser.mService.injectCurrentTimeMillis());
 
@@ -373,7 +419,7 @@
 
             return oldShortcut;
         } else {
-            deleteShortcutInner(shortcutId);
+            forceDeleteShortcutInner(shortcutId);
             return null;
         }
     }
@@ -381,11 +427,25 @@
     public void enableWithId(@NonNull String shortcutId) {
         final ShortcutInfo shortcut = mShortcuts.get(shortcutId);
         if (shortcut != null) {
-            ensureNotImmutable(shortcut);
+            ensureNotImmutable(shortcut, /*ignoreInvisible=*/ true);
             shortcut.clearFlags(ShortcutInfo.FLAG_DISABLED);
+            shortcut.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
         }
     }
 
+    public void updateInvisibleShortcutForPinRequestWith(@NonNull ShortcutInfo shortcut) {
+        final ShortcutInfo source = mShortcuts.get(shortcut.getId());
+        Preconditions.checkNotNull(source);
+
+        mShortcutUser.mService.validateShortcutForPinRequest(shortcut);
+
+        shortcut.addFlags(ShortcutInfo.FLAG_PINNED);
+
+        forceReplaceShortcutInner(shortcut);
+
+        adjustRanks();
+    }
+
     /**
      * Called after a launcher updates the pinned set.  For each shortcut in this package,
      * set FLAG_PINNED if any launcher has pinned it.  Otherwise, clear it.
@@ -510,7 +570,7 @@
      */
     public void findAll(@NonNull List<ShortcutInfo> result,
             @Nullable Predicate<ShortcutInfo> query, int cloneFlag) {
-        findAll(result, query, cloneFlag, null, 0);
+        findAll(result, query, cloneFlag, null, 0, /*getPinnedByAnyLauncher=*/ false);
     }
 
     /**
@@ -522,7 +582,7 @@
      */
     public void findAll(@NonNull List<ShortcutInfo> result,
             @Nullable Predicate<ShortcutInfo> query, int cloneFlag,
-            @Nullable String callingLauncher, int launcherUserId) {
+            @Nullable String callingLauncher, int launcherUserId, boolean getPinnedByAnyLauncher) {
         if (getPackageInfo().isShadow()) {
             // Restored and the app not installed yet, so don't return any.
             return;
@@ -544,9 +604,11 @@
             final boolean isPinnedByCaller = (callingLauncher == null)
                     || ((pinnedByCallerSet != null) && pinnedByCallerSet.contains(si.getId()));
 
-            if (si.isFloating()) {
-                if (!isPinnedByCaller) {
-                    continue;
+            if (!getPinnedByAnyLauncher) {
+                if (si.isFloating()) {
+                    if (!isPinnedByCaller) {
+                        continue;
+                    }
                 }
             }
             final ShortcutInfo clone = si.clone(cloneFlag);
@@ -693,7 +755,27 @@
                     getPackageInfo().getVersionCode(), pi.versionCode));
         }
 
-        getPackageInfo().updateVersionInfo(pi);
+        getPackageInfo().updateFromPackageInfo(pi);
+        final int newVersionCode = getPackageInfo().getVersionCode();
+
+        // See if there are any shortcuts that were prevented restoring because the app was of a
+        // lower version, and re-enable them.
+        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+            final ShortcutInfo si = mShortcuts.valueAt(i);
+            if (si.getDisabledReason() != ShortcutInfo.DISABLED_REASON_VERSION_LOWER) {
+                continue;
+            }
+            if (getPackageInfo().getBackupSourceVersionCode() > newVersionCode) {
+                if (ShortcutService.DEBUG) {
+                    Slog.d(TAG, String.format("Shortcut %s require version %s, still not restored.",
+                            si.getId(), getPackageInfo().getBackupSourceVersionCode()));
+                }
+                continue;
+            }
+            Slog.i(TAG, String.format("Restoring shortcut: %s", si.getId()));
+            si.clearFlags(ShortcutInfo.FLAG_DISABLED);
+            si.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
+        }
 
         // For existing shortcuts, update timestamps if they have any resources.
         // Also check if shortcuts' activities are still main activities.  Otherwise, disable them.
@@ -713,7 +795,8 @@
                         Slog.w(TAG, String.format(
                                 "%s is no longer main activity. Disabling shorcut %s.",
                                 getPackageName(), si.getId()));
-                        if (disableDynamicWithId(si.getId())) {
+                        if (disableDynamicWithId(si.getId(), /*ignoreInvisible*/ false,
+                                ShortcutInfo.DISABLED_REASON_APP_CHANGED)) {
                             continue; // Actually removed.
                         }
                         // Still pinned, so fall-through and possibly update the resources.
@@ -809,7 +892,7 @@
 
                 // Note even if enabled=false, we still need to update all fields, so do it
                 // regardless.
-                addShortcutInner(newShortcut); // This will clean up the old one too.
+                forceReplaceShortcutInner(newShortcut); // This will clean up the old one too.
 
                 if (!newDisabled && toDisableList != null) {
                     // Still alive, don't remove.
@@ -831,7 +914,8 @@
                 final String id = toDisableList.valueAt(i);
 
                 disableWithId(id, /* disable message =*/ null, /* disable message resid */ 0,
-                        /* overrideImmutable=*/ true);
+                        /* overrideImmutable=*/ true, /*ignoreInvisible=*/ false,
+                        ShortcutInfo.DISABLED_REASON_APP_CHANGED);
             }
             removeOrphans();
         }
@@ -869,7 +953,7 @@
                     service.wtf("Found manifest shortcuts in excess list.");
                     continue;
                 }
-                deleteDynamicWithId(shortcut.getId());
+                deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true);
             }
         }
 
@@ -1075,7 +1159,7 @@
         if (ret != 0) {
             return ret;
         }
-        // If they're stil tie, just sort by their IDs.
+        // If they're still tie, just sort by their IDs.
         // This may happen with updateShortcuts() -- see
         // the testUpdateShortcuts_noManifestShortcuts() test.
         return a.getId().compareTo(b.getId());
@@ -1257,25 +1341,34 @@
         ShortcutService.writeAttr(out, ATTR_NAME, getPackageName());
         ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount);
         ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
-        getPackageInfo().saveToXml(out);
+        getPackageInfo().saveToXml(out, forBackup);
 
         for (int j = 0; j < size; j++) {
-            saveShortcut(out, mShortcuts.valueAt(j), forBackup);
+            saveShortcut(out, mShortcuts.valueAt(j), forBackup,
+                    getPackageInfo().isBackupAllowed());
         }
 
         out.endTag(null, TAG_ROOT);
     }
 
-    private void saveShortcut(XmlSerializer out, ShortcutInfo si, boolean forBackup)
+    private void saveShortcut(XmlSerializer out, ShortcutInfo si, boolean forBackup,
+            boolean appSupportsBackup)
             throws IOException, XmlPullParserException {
 
         final ShortcutService s = mShortcutUser.mService;
 
         if (forBackup) {
             if (!(si.isPinned() && si.isEnabled())) {
-                return; // We only backup pinned shortcuts that are enabled.
+                // We only backup pinned shortcuts that are enabled.
+                // Note, this means, shortcuts that are restored but are blocked restore, e.g. due
+                // to a lower version code, will not be ported to a new device.
+                return;
             }
         }
+        final boolean shouldBackupDetails =
+                !forBackup // It's not backup
+                || appSupportsBackup; // Or, it's a backup and app supports backup.
+
         // Note: at this point no shortcuts should have bitmaps pending save, but if they do,
         // just remove the bitmap.
         if (si.isIconPendingSave()) {
@@ -1292,20 +1385,31 @@
         ShortcutService.writeAttr(out, ATTR_TEXT, si.getText());
         ShortcutService.writeAttr(out, ATTR_TEXT_RES_ID, si.getTextResId());
         ShortcutService.writeAttr(out, ATTR_TEXT_RES_NAME, si.getTextResName());
-        ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE, si.getDisabledMessage());
-        ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE_RES_ID,
-                si.getDisabledMessageResourceId());
-        ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE_RES_NAME,
-                si.getDisabledMessageResName());
+        if (shouldBackupDetails) {
+            ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE, si.getDisabledMessage());
+            ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE_RES_ID,
+                    si.getDisabledMessageResourceId());
+            ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE_RES_NAME,
+                    si.getDisabledMessageResName());
+        }
+        ShortcutService.writeAttr(out, ATTR_DISABLED_REASON, si.getDisabledReason());
         ShortcutService.writeAttr(out, ATTR_TIMESTAMP,
                 si.getLastChangedTimestamp());
         if (forBackup) {
             // Don't write icon information.  Also drop the dynamic flag.
-            ShortcutService.writeAttr(out, ATTR_FLAGS,
-                    si.getFlags() &
-                            ~(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES
+
+            int flags = si.getFlags() &
+                    ~(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES
                             | ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE
-                            | ShortcutInfo.FLAG_DYNAMIC));
+                            | ShortcutInfo.FLAG_DYNAMIC);
+            ShortcutService.writeAttr(out, ATTR_FLAGS, flags);
+
+            // Set the publisher version code at every backup.
+            final int packageVersionCode = getPackageInfo().getVersionCode();
+            if (packageVersionCode == 0) {
+                s.wtf("Package version code should be available at this point.");
+                // However, 0 is a valid version code, so we just go ahead with it...
+            }
         } else {
             // When writing for backup, ranks shouldn't be saved, since shortcuts won't be restored
             // as dynamic.
@@ -1317,26 +1421,28 @@
             ShortcutService.writeAttr(out, ATTR_BITMAP_PATH, si.getBitmapPath());
         }
 
-        {
-            final Set<String> cat = si.getCategories();
-            if (cat != null && cat.size() > 0) {
-                out.startTag(null, TAG_CATEGORIES);
-                XmlUtils.writeStringArrayXml(cat.toArray(new String[cat.size()]),
-                        NAME_CATEGORIES, out);
-                out.endTag(null, TAG_CATEGORIES);
+        if (shouldBackupDetails) {
+            {
+                final Set<String> cat = si.getCategories();
+                if (cat != null && cat.size() > 0) {
+                    out.startTag(null, TAG_CATEGORIES);
+                    XmlUtils.writeStringArrayXml(cat.toArray(new String[cat.size()]),
+                            NAME_CATEGORIES, out);
+                    out.endTag(null, TAG_CATEGORIES);
+                }
             }
-        }
-        final Intent[] intentsNoExtras = si.getIntentsNoExtras();
-        final PersistableBundle[] intentsExtras = si.getIntentPersistableExtrases();
-        final int numIntents = intentsNoExtras.length;
-        for (int i = 0; i < numIntents; i++) {
-            out.startTag(null, TAG_INTENT);
-            ShortcutService.writeAttr(out, ATTR_INTENT_NO_EXTRA, intentsNoExtras[i]);
-            ShortcutService.writeTagExtra(out, TAG_EXTRAS, intentsExtras[i]);
-            out.endTag(null, TAG_INTENT);
-        }
+            final Intent[] intentsNoExtras = si.getIntentsNoExtras();
+            final PersistableBundle[] intentsExtras = si.getIntentPersistableExtrases();
+            final int numIntents = intentsNoExtras.length;
+            for (int i = 0; i < numIntents; i++) {
+                out.startTag(null, TAG_INTENT);
+                ShortcutService.writeAttr(out, ATTR_INTENT_NO_EXTRA, intentsNoExtras[i]);
+                ShortcutService.writeTagExtra(out, TAG_EXTRAS, intentsExtras[i]);
+                out.endTag(null, TAG_INTENT);
+            }
 
-        ShortcutService.writeTagExtra(out, TAG_EXTRAS, si.getExtras());
+            ShortcutService.writeTagExtra(out, TAG_EXTRAS, si.getExtras());
+        }
 
         out.endTag(null, TAG_SHORTCUT);
     }
@@ -1356,6 +1462,7 @@
         ret.mLastResetTime =
                 ShortcutService.parseLongAttribute(parser, ATTR_LAST_RESET);
 
+
         final int outerDepth = parser.getDepth();
         int type;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -1369,10 +1476,11 @@
                 switch (tag) {
                     case ShortcutPackageInfo.TAG_ROOT:
                         ret.getPackageInfo().loadFromXml(parser, fromBackup);
+
                         continue;
                     case TAG_SHORTCUT:
                         final ShortcutInfo si = parseShortcut(parser, packageName,
-                                shortcutUser.getUserId());
+                                shortcutUser.getUserId(), fromBackup);
 
                         // Don't use addShortcut(), we don't need to save the icon.
                         ret.mShortcuts.put(si.getId(), si);
@@ -1385,7 +1493,8 @@
     }
 
     private static ShortcutInfo parseShortcut(XmlPullParser parser, String packageName,
-            @UserIdInt int userId) throws IOException, XmlPullParserException {
+            @UserIdInt int userId, boolean fromBackup)
+            throws IOException, XmlPullParserException {
         String id;
         ComponentName activityComponent;
         // Icon icon;
@@ -1398,6 +1507,7 @@
         String disabledMessage;
         int disabledMessageResId;
         String disabledMessageResName;
+        int disabledReason;
         Intent intentLegacy;
         PersistableBundle intentPersistableExtrasLegacy = null;
         ArrayList<Intent> intents = new ArrayList<>();
@@ -1408,6 +1518,7 @@
         int iconResId;
         String iconResName;
         String bitmapPath;
+        int backupVersionCode;
         ArraySet<String> categories = null;
 
         id = ShortcutService.parseStringAttribute(parser, ATTR_ID);
@@ -1424,6 +1535,7 @@
                 ATTR_DISABLED_MESSAGE_RES_ID);
         disabledMessageResName = ShortcutService.parseStringAttribute(parser,
                 ATTR_DISABLED_MESSAGE_RES_NAME);
+        disabledReason = ShortcutService.parseIntAttribute(parser, ATTR_DISABLED_REASON);
         intentLegacy = ShortcutService.parseIntentAttributeNoDefault(parser, ATTR_INTENT_LEGACY);
         rank = (int) ShortcutService.parseLongAttribute(parser, ATTR_RANK);
         lastChangedTimestamp = ShortcutService.parseLongAttribute(parser, ATTR_TIMESTAMP);
@@ -1480,6 +1592,19 @@
             intents.add(intentLegacy);
         }
 
+
+        if ((disabledReason == ShortcutInfo.DISABLED_REASON_NOT_DISABLED)
+                && ((flags & ShortcutInfo.FLAG_DISABLED) != 0)) {
+            // We didn't used to have the disabled reason, so if a shortcut is disabled
+            // and has no reason, we assume it was disabled by publisher.
+            disabledReason = ShortcutInfo.DISABLED_REASON_BY_APP;
+        }
+
+        // All restored shortcuts are initially "shadow".
+        if (fromBackup) {
+            flags |= ShortcutInfo.FLAG_SHADOW;
+        }
+
         return new ShortcutInfo(
                 userId, id, packageName, activityComponent, /* icon =*/ null,
                 title, titleResId, titleResName, text, textResId, textResName,
@@ -1487,7 +1612,7 @@
                 categories,
                 intents.toArray(new Intent[intents.size()]),
                 rank, extras, lastChangedTimestamp, flags,
-                iconResId, iconResName, bitmapPath);
+                iconResId, iconResName, bitmapPath, disabledReason);
     }
 
     private static Intent parseIntent(XmlPullParser parser)
@@ -1602,6 +1727,20 @@
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " has both resource and bitmap icons");
             }
+            if (si.isEnabled()
+                    != (si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED)) {
+                failed = true;
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+                        + " isEnabled() and getDisabledReason() disagree: "
+                        + si.isEnabled() + " vs " + si.getDisabledReason());
+            }
+            if ((si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_VERSION_LOWER)
+                    && (getPackageInfo().getBackupSourceVersionCode()
+                    == ShortcutInfo.VERSION_CODE_UNKNOWN)) {
+                failed = true;
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+                        + " RESTORED_VERSION_LOWER with no backup source version code.");
+            }
             if (s.isDummyMainActivity(si.getActivity())) {
                 failed = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
index e5a2f5a..3a9bbc8 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
@@ -18,6 +18,7 @@
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.content.pm.PackageInfo;
+import android.content.pm.ShortcutInfo;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -45,32 +46,45 @@
     static final String TAG_ROOT = "package-info";
     private static final String ATTR_VERSION = "version";
     private static final String ATTR_LAST_UPDATE_TIME = "last_udpate_time";
+    private static final String ATTR_BACKUP_SOURCE_VERSION = "bk_src_version";
+    private static final String ATTR_BACKUP_ALLOWED = "allow-backup";
+    private static final String ATTR_BACKUP_SOURCE_BACKUP_ALLOWED = "bk_src_backup-allowed";
     private static final String ATTR_SHADOW = "shadow";
 
     private static final String TAG_SIGNATURE = "signature";
     private static final String ATTR_SIGNATURE_HASH = "hash";
 
-    private static final int VERSION_UNKNOWN = -1;
-
     /**
      * When true, this package information was restored from the previous device, and the app hasn't
      * been installed yet.
      */
     private boolean mIsShadow;
-    private int mVersionCode = VERSION_UNKNOWN;
+    private int mVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
+    private int mBackupSourceVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
     private long mLastUpdateTime;
     private ArrayList<byte[]> mSigHashes;
 
+    // mBackupAllowed didn't used to be parsisted, so we don't restore it from a file.
+    // mBackupAllowed will always start with false, and will have been updated before making a
+    // backup next time, which works file.
+    // We just don't want to print an uninitialzied mBackupAlldowed value on dumpsys, so
+    // we use this boolean to control dumpsys.
+    private boolean mBackupAllowedInitialized;
+    private boolean mBackupAllowed;
+    private boolean mBackupSourceBackupAllowed;
+
     private ShortcutPackageInfo(int versionCode, long lastUpdateTime,
             ArrayList<byte[]> sigHashes, boolean isShadow) {
         mVersionCode = versionCode;
         mLastUpdateTime = lastUpdateTime;
         mIsShadow = isShadow;
         mSigHashes = sigHashes;
+        mBackupAllowed = false; // By default, we assume false.
+        mBackupSourceBackupAllowed = false;
     }
 
     public static ShortcutPackageInfo newEmpty() {
-        return new ShortcutPackageInfo(VERSION_UNKNOWN, /* last update time =*/ 0,
+        return new ShortcutPackageInfo(ShortcutInfo.VERSION_CODE_UNKNOWN, /* last update time =*/ 0,
                 new ArrayList<>(0), /* isShadow */ false);
     }
 
@@ -86,15 +100,33 @@
         return mVersionCode;
     }
 
+    public int getBackupSourceVersionCode() {
+        return mBackupSourceVersionCode;
+    }
+
+    @VisibleForTesting
+    public boolean isBackupSourceBackupAllowed() {
+        return mBackupSourceBackupAllowed;
+    }
+
     public long getLastUpdateTime() {
         return mLastUpdateTime;
     }
 
-    /** Set {@link #mVersionCode} and {@link #mLastUpdateTime} from a {@link PackageInfo}. */
-    public void updateVersionInfo(@NonNull PackageInfo pi) {
+    public boolean isBackupAllowed() {
+        return mBackupAllowed;
+    }
+
+    /**
+     * Set {@link #mVersionCode}, {@link #mLastUpdateTime} and {@link #mBackupAllowed}
+     * from a {@link PackageInfo}.
+     */
+    public void updateFromPackageInfo(@NonNull PackageInfo pi) {
         if (pi != null) {
             mVersionCode = pi.versionCode;
             mLastUpdateTime = pi.lastUpdateTime;
+            mBackupAllowed = ShortcutService.shouldBackupApp(pi);
+            mBackupAllowedInitialized = true;
         }
     }
 
@@ -102,23 +134,24 @@
         return mSigHashes.size() > 0;
     }
 
-    public boolean canRestoreTo(ShortcutService s, PackageInfo target) {
-        if (!s.shouldBackupApp(target)) {
-            // "allowBackup" was true when backed up, but now false.
-            Slog.w(TAG, "Can't restore: package no longer allows backup");
-            return false;
+    //@DisabledReason
+    public int canRestoreTo(ShortcutService s, PackageInfo currentPackage, boolean anyVersionOkay) {
+        if (!BackupUtils.signaturesMatch(mSigHashes, currentPackage)) {
+            Slog.w(TAG, "Can't restore: Package signature mismatch");
+            return ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH;
         }
-        if (target.versionCode < mVersionCode) {
+        if (!ShortcutService.shouldBackupApp(currentPackage) || !mBackupSourceBackupAllowed) {
+            // "allowBackup" was true when backed up, but now false.
+            Slog.w(TAG, "Can't restore: package didn't or doesn't allow backup");
+            return ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED;
+        }
+        if (!anyVersionOkay && (currentPackage.versionCode < mBackupSourceVersionCode)) {
             Slog.w(TAG, String.format(
                     "Can't restore: package current version %d < backed up version %d",
-                    target.versionCode, mVersionCode));
-            return false;
+                    currentPackage.versionCode, mBackupSourceVersionCode));
+            return ShortcutInfo.DISABLED_REASON_VERSION_LOWER;
         }
-        if (!BackupUtils.signaturesMatch(mSigHashes, target)) {
-            Slog.w(TAG, "Can't restore: Package signature mismatch");
-            return false;
-        }
-        return true;
+        return ShortcutInfo.DISABLED_REASON_NOT_DISABLED;
     }
 
     @VisibleForTesting
@@ -132,6 +165,8 @@
         final ShortcutPackageInfo ret = new ShortcutPackageInfo(pi.versionCode, pi.lastUpdateTime,
                 BackupUtils.hashSignatureArray(pi.signatures), /* shadow=*/ false);
 
+        ret.mBackupSourceBackupAllowed = s.shouldBackupApp(pi);
+        ret.mBackupSourceVersionCode = pi.versionCode;
         return ret;
     }
 
@@ -151,13 +186,19 @@
         mSigHashes = BackupUtils.hashSignatureArray(pi.signatures);
     }
 
-    public void saveToXml(XmlSerializer out) throws IOException {
+    public void saveToXml(XmlSerializer out, boolean forBackup) throws IOException {
 
         out.startTag(null, TAG_ROOT);
 
         ShortcutService.writeAttr(out, ATTR_VERSION, mVersionCode);
         ShortcutService.writeAttr(out, ATTR_LAST_UPDATE_TIME, mLastUpdateTime);
         ShortcutService.writeAttr(out, ATTR_SHADOW, mIsShadow);
+        ShortcutService.writeAttr(out, ATTR_BACKUP_ALLOWED, mBackupAllowed);
+
+        ShortcutService.writeAttr(out, ATTR_BACKUP_SOURCE_VERSION, mBackupSourceVersionCode);
+        ShortcutService.writeAttr(out,
+                ATTR_BACKUP_SOURCE_BACKUP_ALLOWED, mBackupSourceBackupAllowed);
+
 
         for (int i = 0; i < mSigHashes.size(); i++) {
             out.startTag(null, TAG_SIGNATURE);
@@ -171,7 +212,9 @@
     public void loadFromXml(XmlPullParser parser, boolean fromBackup)
             throws IOException, XmlPullParserException {
 
-        final int versionCode = ShortcutService.parseIntAttribute(parser, ATTR_VERSION);
+        // Don't use the version code from the backup file.
+        final int versionCode = ShortcutService.parseIntAttribute(parser, ATTR_VERSION,
+                ShortcutInfo.VERSION_CODE_UNKNOWN);
 
         final long lastUpdateTime = ShortcutService.parseLongAttribute(
                 parser, ATTR_LAST_UPDATE_TIME);
@@ -180,6 +223,20 @@
         final boolean shadow =
                 fromBackup || ShortcutService.parseBooleanAttribute(parser, ATTR_SHADOW);
 
+        // We didn't used to save these attributes, and all backed up shortcuts were from
+        // apps that support backups, so the default values take this fact into consideration.
+        final int backupSourceVersion = ShortcutService.parseIntAttribute(parser,
+                ATTR_BACKUP_SOURCE_VERSION, ShortcutInfo.VERSION_CODE_UNKNOWN);
+
+        // Note the only time these "true" default value is used is when restoring from an old
+        // build that didn't save ATTR_BACKUP_ALLOWED, and that means all the data included in
+        // a backup file were from apps that support backup, so we can just use "true" as the
+        // default.
+        final boolean backupAllowed = ShortcutService.parseBooleanAttribute(
+                parser, ATTR_BACKUP_ALLOWED, true);
+        final boolean backupSourceBackupAllowed = ShortcutService.parseBooleanAttribute(
+                parser, ATTR_BACKUP_SOURCE_BACKUP_ALLOWED, true);
+
         final ArrayList<byte[]> hashes = new ArrayList<>();
 
         final int outerDepth = parser.getDepth();
@@ -207,11 +264,28 @@
             ShortcutService.warnForInvalidTag(depth, tag);
         }
 
-        // Successfully loaded; replace the feilds.
-        mVersionCode = versionCode;
+        // Successfully loaded; replace the fields.
+        if (fromBackup) {
+            mVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
+            mBackupSourceVersionCode = versionCode;
+            mBackupSourceBackupAllowed = backupAllowed;
+        } else {
+            mVersionCode = versionCode;
+            mBackupSourceVersionCode = backupSourceVersion;
+            mBackupSourceBackupAllowed = backupSourceBackupAllowed;
+        }
         mLastUpdateTime = lastUpdateTime;
         mIsShadow = shadow;
         mSigHashes = hashes;
+
+        // Note we don't restore it from the file because it didn't used to be saved.
+        // We always start by assuming backup is disabled for the current package,
+        // and this field will have been updated before we actually create a backup, at the same
+        // time when we update the version code.
+        // Until then, the value of mBackupAllowed shouldn't matter, but we don't want to print
+        // a false flag on dumpsys, so set mBackupAllowedInitialized to false.
+        mBackupAllowed = false;
+        mBackupAllowedInitialized = false;
     }
 
     public void dump(PrintWriter pw, String prefix) {
@@ -223,6 +297,7 @@
         pw.print(prefix);
         pw.print("  IsShadow: ");
         pw.print(mIsShadow);
+        pw.print(mIsShadow ? " (not installed)" : " (installed)");
         pw.println();
 
         pw.print(prefix);
@@ -230,6 +305,25 @@
         pw.print(mVersionCode);
         pw.println();
 
+        if (mBackupAllowedInitialized) {
+            pw.print(prefix);
+            pw.print("  Backup Allowed: ");
+            pw.print(mBackupAllowed);
+            pw.println();
+        }
+
+        if (mBackupSourceVersionCode != ShortcutInfo.VERSION_CODE_UNKNOWN) {
+            pw.print(prefix);
+            pw.print("  Backup source version: ");
+            pw.print(mBackupSourceVersionCode);
+            pw.println();
+
+            pw.print(prefix);
+            pw.print("  Backup source backup allowed: ");
+            pw.print(mBackupSourceBackupAllowed);
+            pw.println();
+        }
+
         pw.print(prefix);
         pw.print("  Last package update time: ");
         pw.print(mLastUpdateTime);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
index e59d69f..689099c 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -17,6 +17,7 @@
 
 import android.annotation.NonNull;
 import android.content.pm.PackageInfo;
+import android.content.pm.ShortcutInfo;
 import android.util.Slog;
 
 import com.android.internal.util.Preconditions;
@@ -101,51 +102,42 @@
         final ShortcutService s = mShortcutUser.mService;
         if (!s.isPackageInstalled(mPackageName, mPackageUserId)) {
             if (ShortcutService.DEBUG) {
-                Slog.d(TAG, String.format("Package still not installed: %s user=%d",
+                Slog.d(TAG, String.format("Package still not installed: %s/u%d",
                         mPackageName, mPackageUserId));
             }
             return; // Not installed, no need to restore yet.
         }
-        boolean blockRestore = false;
-        if (!mPackageInfo.hasSignatures()) {
-            s.wtf("Attempted to restore package " + mPackageName + ", user=" + mPackageUserId
-                    + " but signatures not found in the restore data.");
-            blockRestore = true;
-        }
-        if (!blockRestore) {
-            final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId);
-            if (!mPackageInfo.canRestoreTo(s, pi)) {
-                // Package is now installed, but can't restore.  Let the subclass do the cleanup.
-                blockRestore = true;
-            }
-        }
-        if (blockRestore) {
-            onRestoreBlocked();
-        } else {
-            if (ShortcutService.DEBUG) {
-                Slog.d(TAG, String.format("Restored package: %s/%d on user %d", mPackageName,
-                        mPackageUserId, getOwnerUserId()));
-            }
+        int restoreBlockReason;
+        int currentVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
 
-            onRestored();
+        if (!mPackageInfo.hasSignatures()) {
+            s.wtf("Attempted to restore package " + mPackageName + "/u" + mPackageUserId
+                    + " but signatures not found in the restore data.");
+            restoreBlockReason = ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH;
+        } else {
+            final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId);
+            currentVersionCode = pi.versionCode;
+            restoreBlockReason = mPackageInfo.canRestoreTo(s, pi, canRestoreAnyVersion());
         }
 
+        if (ShortcutService.DEBUG) {
+            Slog.d(TAG, String.format("Restoring package: %s/u%d (version=%d) %s for u%d",
+                    mPackageName, mPackageUserId, currentVersionCode,
+                    ShortcutInfo.getDisabledReasonDebugString(restoreBlockReason),
+                    getOwnerUserId()));
+        }
+
+        onRestored(restoreBlockReason);
+
         // Either way, it's no longer a shadow.
         mPackageInfo.setShadow(false);
 
         s.scheduleSaveUser(mPackageUserId);
     }
 
-    /**
-     * Called when the new package can't be restored because it has a lower version number
-     * or different signatures.
-     */
-    protected abstract void onRestoreBlocked();
+    protected abstract boolean canRestoreAnyVersion();
 
-    /**
-     * Called when the new package is successfully restored.
-     */
-    protected abstract void onRestored();
+    protected abstract void onRestored(int restoreBlockReason);
 
     public abstract void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
             throws IOException, XmlPullParserException;
diff --git a/services/core/java/com/android/server/pm/ShortcutParser.java b/services/core/java/com/android/server/pm/ShortcutParser.java
index 3cf4200..866c46c 100644
--- a/services/core/java/com/android/server/pm/ShortcutParser.java
+++ b/services/core/java/com/android/server/pm/ShortcutParser.java
@@ -337,6 +337,9 @@
                 (enabled ? ShortcutInfo.FLAG_MANIFEST : ShortcutInfo.FLAG_DISABLED)
                 | ShortcutInfo.FLAG_IMMUTABLE
                 | ((iconResId != 0) ? ShortcutInfo.FLAG_HAS_ICON_RES : 0);
+        final int disabledReason =
+                enabled ? ShortcutInfo.DISABLED_REASON_NOT_DISABLED
+                        : ShortcutInfo.DISABLED_REASON_BY_APP;
 
         // Note we don't need to set resource names here yet.  They'll be set when they're about
         // to be published.
@@ -363,6 +366,7 @@
                 flags,
                 iconResId,
                 null, // icon res name
-                null); // bitmap path
+                null, // bitmap path
+                disabledReason);
     }
 }
diff --git a/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
index 8a8128d..3e44de9 100644
--- a/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
+++ b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
@@ -300,10 +300,12 @@
 
         final ShortcutInfo existing = ps.findShortcutById(inShortcut.getId());
         final boolean existsAlready = existing != null;
+        final boolean existingIsVisible = existsAlready && existing.isVisibleToPublisher();
 
         if (DEBUG) {
             Slog.d(TAG, "requestPinnedShortcut: package=" + inShortcut.getPackage()
                     + " existsAlready=" + existsAlready
+                    + " existingIsVisible=" + existingIsVisible
                     + " shortcut=" + inShortcut.toInsecureString());
         }
 
@@ -378,7 +380,6 @@
         // manifest shortcut.)
         Preconditions.checkArgument(shortcutInfo.isEnabled(),
                 "Shortcut ID=" + shortcutInfo + " already exists but disabled.");
-
     }
 
     private boolean startRequestConfirmActivity(ComponentName activity, int launcherUserId,
@@ -463,7 +464,7 @@
             launcher.attemptToRestoreIfNeededAndSave();
             if (launcher.hasPinned(original)) {
                 if (DEBUG) {
-                    Slog.d(TAG, "Shortcut " + original + " already pinned.");
+                    Slog.d(TAG, "Shortcut " + original + " already pinned.");                       // This too.
                 }
                 return true;
             }
@@ -497,7 +498,7 @@
                 if (original.getActivity() == null) {
                     original.setActivity(mService.getDummyMainActivity(appPackageName));
                 }
-                ps.addOrUpdateDynamicShortcut(original);
+                ps.addOrReplaceDynamicShortcut(original);
             }
 
             // Pin the shortcut.
@@ -505,13 +506,14 @@
                 Slog.d(TAG, "Pinning " + shortcutId);
             }
 
-            launcher.addPinnedShortcut(appPackageName, appUserId, shortcutId);
+            launcher.addPinnedShortcut(appPackageName, appUserId, shortcutId,
+                    /*forPinRequest=*/ true);
 
             if (current == null) {
                 if (DEBUG) {
                     Slog.d(TAG, "Removing " + shortcutId + " as dynamic");
                 }
-                ps.deleteDynamicWithId(shortcutId);
+                ps.deleteDynamicWithId(shortcutId, /*ignoreInvisible=*/ false);
             }
 
             ps.adjustRanks(); // Shouldn't be needed, but just in case.
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 27560c5f..1c002aa 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -553,6 +553,9 @@
 
         public Lifecycle(Context context) {
             super(context);
+            if (DEBUG) {
+                Binder.LOG_RUNTIME_EXCEPTION = true;
+            }
             mService = new ShortcutService(context);
         }
 
@@ -738,6 +741,10 @@
         return parseLongAttribute(parser, attribute) == 1;
     }
 
+    static boolean parseBooleanAttribute(XmlPullParser parser, String attribute, boolean def) {
+        return parseLongAttribute(parser, attribute, (def ? 1 : 0)) == 1;
+    }
+
     static int parseIntAttribute(XmlPullParser parser, String attribute) {
         return (int) parseLongAttribute(parser, attribute);
     }
@@ -835,6 +842,8 @@
     static void writeAttr(XmlSerializer out, String name, boolean value) throws IOException {
         if (value) {
             writeAttr(out, name, "1");
+        } else {
+            writeAttr(out, name, "0");
         }
     }
 
@@ -1689,7 +1698,7 @@
 
             final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
 
-            ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
+            ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
 
             fillInDefaultActivity(newShortcuts);
 
@@ -1709,12 +1718,12 @@
             }
 
             // First, remove all un-pinned; dynamic shortcuts
-            ps.deleteAllDynamicShortcuts();
+            ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true);
 
             // Then, add/update all.  We need to make sure to take over "pinned" flag.
             for (int i = 0; i < size; i++) {
                 final ShortcutInfo newShortcut = newShortcuts.get(i);
-                ps.addOrUpdateDynamicShortcut(newShortcut);
+                ps.addOrReplaceDynamicShortcut(newShortcut);
             }
 
             // Lastly, adjust the ranks.
@@ -1740,7 +1749,7 @@
 
             final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
 
-            ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
+            ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
 
             // For update, don't fill in the default activity.  Having null activity means
             // "don't update the activity" here.
@@ -1761,7 +1770,9 @@
                 fixUpIncomingShortcutInfo(source, /* forUpdate= */ true);
 
                 final ShortcutInfo target = ps.findShortcutById(source.getId());
-                if (target == null) {
+
+                // Invisible shortcuts can't be updated.
+                if (target == null || !target.isVisibleToPublisher()) {
                     continue;
                 }
 
@@ -1808,7 +1819,7 @@
     }
 
     @Override
-    public boolean addDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
+    public boolean  addDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
@@ -1820,7 +1831,7 @@
 
             final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
 
-            ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
+            ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
 
             fillInDefaultActivity(newShortcuts);
 
@@ -1845,7 +1856,7 @@
                 newShortcut.setRankChanged();
 
                 // Add it.
-                ps.addOrUpdateDynamicShortcut(newShortcut);
+                ps.addOrReplaceDynamicShortcut(newShortcut);
             }
 
             // Lastly, adjust the ranks.
@@ -1901,6 +1912,22 @@
             Preconditions.checkState(isUidForegroundLocked(injectBinderCallingUid()),
                     "Calling application must have a foreground activity or a foreground service");
 
+            // If it's a pin shortcut request, and there's already a shortcut with the same ID
+            // that's not visible to the caller (i.e. restore-blocked; meaning it's pinned by
+            // someone already), then we just replace the existing one with this new one,
+            // and then proceed the rest of the process.
+            if (shortcut != null) {
+                final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(
+                        packageName, userId);
+                final String id = shortcut.getId();
+                if (ps.isShortcutExistsAndInvisibleToPublisher(id)) {
+
+                    ps.updateInvisibleShortcutForPinRequestWith(shortcut);
+
+                    packageShortcutsChanged(packageName, userId);
+                }
+            }
+
             // Send request to the launcher, if supported.
             ret = mShortcutRequestPinProcessor.requestPinItemLocked(shortcut, appWidget, extras,
                     userId, resultIntent);
@@ -1922,15 +1949,21 @@
 
             final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
 
-            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);
+            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds,
+                    /*ignoreInvisible=*/ true);
 
             final String disabledMessageString =
                     (disabledMessage == null) ? null : disabledMessage.toString();
 
             for (int i = shortcutIds.size() - 1; i >= 0; i--) {
-                ps.disableWithId(Preconditions.checkStringNotEmpty((String) shortcutIds.get(i)),
+                final String id = Preconditions.checkStringNotEmpty((String) shortcutIds.get(i));
+                if (!ps.isShortcutExistsAndVisibleToPublisher(id)) {
+                    continue;
+                }
+                ps.disableWithId(id,
                         disabledMessageString, disabledMessageResId,
-                        /* overrideImmutable=*/ false);
+                        /* overrideImmutable=*/ false, /*ignoreInvisible=*/ true,
+                        ShortcutInfo.DISABLED_REASON_BY_APP);
             }
 
             // We may have removed dynamic shortcuts which may have left a gap, so adjust the ranks.
@@ -1951,10 +1984,15 @@
 
             final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
 
-            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);
+            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds,
+                    /*ignoreInvisible=*/ true);
 
             for (int i = shortcutIds.size() - 1; i >= 0; i--) {
-                ps.enableWithId((String) shortcutIds.get(i));
+                final String id = Preconditions.checkStringNotEmpty((String) shortcutIds.get(i));
+                if (!ps.isShortcutExistsAndVisibleToPublisher(id)) {
+                    continue;
+                }
+                ps.enableWithId(id);
             }
         }
         packageShortcutsChanged(packageName, userId);
@@ -1973,11 +2011,15 @@
 
             final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
 
-            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);
+            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds,
+                    /*ignoreInvisible=*/ true);
 
             for (int i = shortcutIds.size() - 1; i >= 0; i--) {
-                ps.deleteDynamicWithId(
-                        Preconditions.checkStringNotEmpty((String) shortcutIds.get(i)));
+                final String id = Preconditions.checkStringNotEmpty((String) shortcutIds.get(i));
+                if (!ps.isShortcutExistsAndVisibleToPublisher(id)) {
+                    continue;
+                }
+                ps.deleteDynamicWithId(id, /*ignoreInvisible=*/ true);
             }
 
             // We may have removed dynamic shortcuts which may have left a gap, so adjust the ranks.
@@ -1996,7 +2038,7 @@
             throwIfUserLockedL(userId);
 
             final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
-            ps.deleteAllDynamicShortcuts();
+            ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true);
         }
         packageShortcutsChanged(packageName, userId);
 
@@ -2013,7 +2055,7 @@
 
             return getShortcutsWithQueryLocked(
                     packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
-                    ShortcutInfo::isDynamic);
+                    ShortcutInfo::isDynamicVisible);
         }
     }
 
@@ -2027,7 +2069,7 @@
 
             return getShortcutsWithQueryLocked(
                     packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
-                    ShortcutInfo::isManifestShortcut);
+                    ShortcutInfo::isManifestVisible);
         }
     }
 
@@ -2041,7 +2083,7 @@
 
             return getShortcutsWithQueryLocked(
                     packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
-                    ShortcutInfo::isPinned);
+                    ShortcutInfo::isPinnedVisible);
         }
     }
 
@@ -2190,7 +2232,11 @@
     }
 
     // We override this method in unit tests to do a simpler check.
-    boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) {
+    boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId,
+            int callingPid, int callingUid) {
+        if (injectCheckAccessShortcutsPermission(callingPid, callingUid)) {
+            return true;
+        }
         final long start = injectElapsedRealtime();
         try {
             return hasShortcutHostPermissionInner(callingPackage, userId);
@@ -2199,6 +2245,14 @@
         }
     }
 
+    /**
+     * Returns true if the caller has the "ACCESS_SHORTCUTS" permission.
+     */
+    boolean injectCheckAccessShortcutsPermission(int callingPid, int callingUid) {
+        return mContext.checkPermission(android.Manifest.permission.ACCESS_SHORTCUTS,
+                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
+    }
+
     // This method is extracted so we can directly call this method from unit tests,
     // even when hasShortcutPermission() is overridden.
     @VisibleForTesting
@@ -2379,7 +2433,7 @@
                 @NonNull String callingPackage, long changedSince,
                 @Nullable String packageName, @Nullable List<String> shortcutIds,
                 @Nullable ComponentName componentName,
-                int queryFlags, int userId) {
+                int queryFlags, int userId, int callingPid, int callingUid) {
             final ArrayList<ShortcutInfo> ret = new ArrayList<>();
 
             final boolean cloneKeyFieldOnly =
@@ -2400,13 +2454,15 @@
                 if (packageName != null) {
                     getShortcutsInnerLocked(launcherUserId,
                             callingPackage, packageName, shortcutIds, changedSince,
-                            componentName, queryFlags, userId, ret, cloneFlag);
+                            componentName, queryFlags, userId, ret, cloneFlag,
+                            callingPid, callingUid);
                 } else {
                     final List<String> shortcutIdsF = shortcutIds;
                     getUserShortcutsLocked(userId).forAllPackages(p -> {
                         getShortcutsInnerLocked(launcherUserId,
                                 callingPackage, p.getPackageName(), shortcutIdsF, changedSince,
-                                componentName, queryFlags, userId, ret, cloneFlag);
+                                componentName, queryFlags, userId, ret, cloneFlag,
+                                callingPid, callingUid);
                     });
                 }
             }
@@ -2416,7 +2472,8 @@
         private void getShortcutsInnerLocked(int launcherUserId, @NonNull String callingPackage,
                 @Nullable String packageName, @Nullable List<String> shortcutIds, long changedSince,
                 @Nullable ComponentName componentName, int queryFlags,
-                int userId, ArrayList<ShortcutInfo> ret, int cloneFlag) {
+                int userId, ArrayList<ShortcutInfo> ret, int cloneFlag,
+                int callingPid, int callingUid) {
             final ArraySet<String> ids = shortcutIds == null ? null
                     : new ArraySet<>(shortcutIds);
 
@@ -2425,6 +2482,13 @@
             if (p == null) {
                 return; // No need to instantiate ShortcutPackage.
             }
+            final boolean matchDynamic = (queryFlags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0;
+            final boolean matchPinned = (queryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0;
+            final boolean matchManifest = (queryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0;
+
+            final boolean getPinnedByAnyLauncher =
+                    ((queryFlags & ShortcutQuery.FLAG_MATCH_ALL_PINNED) != 0)
+                    && injectCheckAccessShortcutsPermission(callingPid, callingUid);
 
             p.findAll(ret,
                     (ShortcutInfo si) -> {
@@ -2440,20 +2504,17 @@
                                 return false;
                             }
                         }
-                        if (((queryFlags & ShortcutQuery.FLAG_GET_DYNAMIC) != 0)
-                                && si.isDynamic()) {
+                        if (matchDynamic && si.isDynamic()) {
                             return true;
                         }
-                        if (((queryFlags & ShortcutQuery.FLAG_GET_PINNED) != 0)
-                                && si.isPinned()) {
+                        if ((matchPinned && si.isPinned()) || getPinnedByAnyLauncher) {
                             return true;
                         }
-                        if (((queryFlags & ShortcutQuery.FLAG_GET_MANIFEST) != 0)
-                                && si.isManifestShortcut()) {
+                        if (matchManifest && si.isDeclaredInManifest()) {
                             return true;
                         }
                         return false;
-                    }, cloneFlag, callingPackage, launcherUserId);
+                    }, cloneFlag, callingPackage, launcherUserId, getPinnedByAnyLauncher);
         }
 
         @Override
@@ -2470,14 +2531,16 @@
                         .attemptToRestoreIfNeededAndSave();
 
                 final ShortcutInfo si = getShortcutInfoLocked(
-                        launcherUserId, callingPackage, packageName, shortcutId, userId);
+                        launcherUserId, callingPackage, packageName, shortcutId, userId,
+                        /*getPinnedByAnyLauncher=*/ false);
                 return si != null && si.isPinned();
             }
         }
 
         private ShortcutInfo getShortcutInfoLocked(
                 int launcherUserId, @NonNull String callingPackage,
-                @NonNull String packageName, @NonNull String shortcutId, int userId) {
+                @NonNull String packageName, @NonNull String shortcutId, int userId,
+                boolean getPinnedByAnyLauncher) {
             Preconditions.checkStringNotEmpty(packageName, "packageName");
             Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
 
@@ -2493,7 +2556,7 @@
             final ArrayList<ShortcutInfo> list = new ArrayList<>(1);
             p.findAll(list,
                     (ShortcutInfo si) -> shortcutId.equals(si.getId()),
-                    /* clone flags=*/ 0, callingPackage, launcherUserId);
+                    /* clone flags=*/ 0, callingPackage, launcherUserId, getPinnedByAnyLauncher);
             return list.size() == 0 ? null : list.get(0);
         }
 
@@ -2513,7 +2576,7 @@
                         getLauncherShortcutsLocked(callingPackage, userId, launcherUserId);
                 launcher.attemptToRestoreIfNeededAndSave();
 
-                launcher.pinShortcuts(userId, packageName, shortcutIds);
+                launcher.pinShortcuts(userId, packageName, shortcutIds, /*forPinRequest=*/ false);
             }
             packageShortcutsChanged(packageName, userId);
 
@@ -2523,7 +2586,8 @@
         @Override
         public Intent[] createShortcutIntents(int launcherUserId,
                 @NonNull String callingPackage,
-                @NonNull String packageName, @NonNull String shortcutId, int userId) {
+                @NonNull String packageName, @NonNull String shortcutId, int userId,
+                int callingPid, int callingUid) {
             // Calling permission must be checked by LauncherAppsImpl.
             Preconditions.checkStringNotEmpty(packageName, "packageName can't be empty");
             Preconditions.checkStringNotEmpty(shortcutId, "shortcutId can't be empty");
@@ -2535,9 +2599,13 @@
                 getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
                         .attemptToRestoreIfNeededAndSave();
 
+                final boolean getPinnedByAnyLauncher =
+                        injectCheckAccessShortcutsPermission(callingPid, callingUid);
+
                 // Make sure the shortcut is actually visible to the launcher.
                 final ShortcutInfo si = getShortcutInfoLocked(
-                        launcherUserId, callingPackage, packageName, shortcutId, userId);
+                        launcherUserId, callingPackage, packageName, shortcutId, userId,
+                        getPinnedByAnyLauncher);
                 // "si == null" should suffice here, but check the flags too just to make sure.
                 if (si == null || !si.isEnabled() || !si.isAlive()) {
                     Log.e(TAG, "Shortcut " + shortcutId + " does not exist or disabled");
@@ -2623,8 +2691,9 @@
 
         @Override
         public boolean hasShortcutHostPermission(int launcherUserId,
-                @NonNull String callingPackage) {
-            return ShortcutService.this.hasShortcutHostPermission(callingPackage, launcherUserId);
+                @NonNull String callingPackage, int callingPid, int callingUid) {
+            return ShortcutService.this.hasShortcutHostPermission(callingPackage, launcherUserId,
+                    callingPid, callingUid);
         }
 
         @Override
@@ -3343,7 +3412,7 @@
         return isApplicationFlagSet(packageName, userId, ApplicationInfo.FLAG_ALLOW_BACKUP);
     }
 
-    boolean shouldBackupApp(PackageInfo pi) {
+    static boolean shouldBackupApp(PackageInfo pi) {
         return (pi.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0;
     }
 
@@ -3371,7 +3440,7 @@
             // Set the version code for the launchers.
             // We shouldn't do this for publisher packages, because we don't want to update the
             // version code without rescanning the manifest.
-            user.forAllLaunchers(launcher -> launcher.ensureVersionInfo());
+            user.forAllLaunchers(launcher -> launcher.ensurePackageInfo());
 
             // Save to the filesystem.
             scheduleSaveUser(userId);
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 55e6d28..48eccd0 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -364,9 +364,6 @@
     private void saveShortcutPackageItem(XmlSerializer out,
             ShortcutPackageItem spi, boolean forBackup) throws IOException, XmlPullParserException {
         if (forBackup) {
-            if (!mService.shouldBackupApp(spi.getPackageName(), spi.getPackageUserId())) {
-                return; // Don't save.
-            }
             if (spi.getPackageUserId() != spi.getOwnerUserId()) {
                 return; // Don't save cross-user information.
             }
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index a6b05d7..c18a71d 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -96,6 +96,7 @@
             UserManager.DISALLOW_SMS,
             UserManager.DISALLOW_FUN,
             UserManager.DISALLOW_CREATE_WINDOWS,
+            UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
             UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
             UserManager.DISALLOW_OUTGOING_BEAM,
             UserManager.DISALLOW_WALLPAPER,
@@ -156,6 +157,7 @@
     private static final Set<String> GLOBAL_RESTRICTIONS = Sets.newArraySet(
             UserManager.DISALLOW_ADJUST_VOLUME,
             UserManager.DISALLOW_BLUETOOTH_SHARING,
+            UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
             UserManager.DISALLOW_RUN_IN_BACKGROUND,
             UserManager.DISALLOW_UNMUTE_MICROPHONE,
             UserManager.DISALLOW_UNMUTE_DEVICE
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 09a6e9c..71d3202 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -48,6 +48,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
@@ -77,7 +78,7 @@
 
     final String name;
 
-    @PermissionType final int type;
+    final @PermissionType int type;
 
     String sourcePackageName;
 
@@ -252,12 +253,12 @@
         return changed;
     }
 
-    public void updateDynamicPermission(Map<String, BasePermission> permissionTrees) {
+    public void updateDynamicPermission(Collection<BasePermission> permissionTrees) {
         if (PackageManagerService.DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
                 + getName() + " pkg=" + getSourcePackageName()
                 + " info=" + pendingPermissionInfo);
         if (sourcePackageSetting == null && pendingPermissionInfo != null) {
-            final BasePermission tree = findPermissionTreeLP(permissionTrees, name);
+            final BasePermission tree = findPermissionTree(permissionTrees, name);
             if (tree != null && tree.perm != null) {
                 sourcePackageSetting = tree.sourcePackageSetting;
                 perm = new PackageParser.Permission(tree.perm.owner,
@@ -269,8 +270,8 @@
         }
     }
 
-    public static BasePermission createOrUpdate(@Nullable BasePermission bp, @NonNull Permission p,
-            @NonNull PackageParser.Package pkg, Map<String, BasePermission> permissionTrees,
+    static BasePermission createOrUpdate(@Nullable BasePermission bp, @NonNull Permission p,
+            @NonNull PackageParser.Package pkg, Collection<BasePermission> permissionTrees,
             boolean chatty) {
         final PackageSettingBase pkgSetting = (PackageSettingBase) pkg.mExtras;
         // Allow system apps to redefine non-system permissions
@@ -300,7 +301,7 @@
         if (bp.perm == null) {
             if (bp.sourcePackageName == null
                     || bp.sourcePackageName.equals(p.info.packageName)) {
-                final BasePermission tree = findPermissionTreeLP(permissionTrees, p.info.name);
+                final BasePermission tree = findPermissionTree(permissionTrees, p.info.name);
                 if (tree == null
                         || tree.sourcePackageName.equals(p.info.packageName)) {
                     bp.sourcePackageSetting = pkgSetting;
@@ -345,12 +346,12 @@
         return bp;
     }
 
-    public static BasePermission enforcePermissionTreeLP(
-            Map<String, BasePermission> permissionTrees, String permName, int callingUid) {
+    static BasePermission enforcePermissionTree(
+            Collection<BasePermission> permissionTrees, String permName, int callingUid) {
         if (permName != null) {
-            BasePermission bp = findPermissionTreeLP(permissionTrees, permName);
+            BasePermission bp = findPermissionTree(permissionTrees, permName);
             if (bp != null) {
-                if (bp.uid == UserHandle.getAppId(callingUid)) {//UserHandle.getAppId(Binder.getCallingUid())) {
+                if (bp.uid == UserHandle.getAppId(callingUid)) {
                     return bp;
                 }
                 throw new SecurityException("Calling uid " + callingUid
@@ -373,9 +374,9 @@
         }
     }
 
-    private static BasePermission findPermissionTreeLP(
-            Map<String, BasePermission> permissionTrees, String permName) {
-        for (BasePermission bp : permissionTrees.values()) {
+    private static BasePermission findPermissionTree(
+            Collection<BasePermission> permissionTrees, String permName) {
+        for (BasePermission bp : permissionTrees) {
             if (permName.startsWith(bp.name) &&
                     permName.length() > bp.name.length() &&
                     permName.charAt(bp.name.length()) == '.') {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
index 3b20b42..8aac52a 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
@@ -31,6 +31,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Internal interfaces to be used by other components within the system server.
@@ -81,11 +82,26 @@
             @NonNull int[] allUserIds);
 
 
-    public abstract boolean addPermission(@NonNull PermissionInfo info, boolean async,
+    /**
+     * Add all permissions in the given package.
+     * <p>
+     * NOTE: argument {@code groupTEMP} is temporary until mPermissionGroups is moved to
+     * the permission settings.
+     */
+    public abstract void addAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty);
+    public abstract void removeAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty);
+    public abstract boolean addDynamicPermission(@NonNull PermissionInfo info, boolean async,
             int callingUid, @Nullable PermissionCallback callback);
-    public abstract void removePermission(@NonNull String permName, int callingUid,
+    public abstract void removeDynamicPermission(@NonNull String permName, int callingUid,
             @Nullable PermissionCallback callback);
 
+    public abstract int updatePermissions(@Nullable String changingPkg,
+            @Nullable PackageParser.Package pkgInfo, int flags);
+    public abstract int updatePermissionTrees(@Nullable String changingPkg,
+            @Nullable PackageParser.Package pkgInfo, int flags);
+
+    public abstract @Nullable String[] getAppOpPermissionPackages(@NonNull String permName);
+
     public abstract int getPermissionFlags(@NonNull String permName,
             @NonNull String packageName, int callingUid, int userId);
     /**
@@ -98,8 +114,6 @@
      */
     public abstract @Nullable List<PermissionInfo> getPermissionInfoByGroup(@NonNull String group,
             @PermissionInfoFlags int flags, int callingUid);
-    public abstract boolean isPermissionAppOp(@NonNull String permName);
-    public abstract boolean isPermissionInstant(@NonNull String permName);
 
     /**
      * Updates the flags associated with a permission by replacing the flags in
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 6c031a6..062aa33 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -69,6 +69,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Manages all permissions and handles permissions related tasks.
@@ -260,7 +261,7 @@
 //            }
 
             final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
-            for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
+            for (BasePermission bp : mSettings.mPermissions.values()) {
                 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
                 if (pi != null) {
                     out.add(pi);
@@ -305,7 +306,98 @@
         return protectionLevel;
     }
 
-    private boolean addPermission(
+    private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
+        final int N = pkg.permissions.size();
+        for (int i=0; i<N; i++) {
+            PackageParser.Permission p = pkg.permissions.get(i);
+
+            // Assume by default that we did not install this permission into the system.
+            p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
+
+            // Now that permission groups have a special meaning, we ignore permission
+            // groups for legacy apps to prevent unexpected behavior. In particular,
+            // permissions for one app being granted to someone just because they happen
+            // to be in a group defined by another app (before this had no implications).
+            if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
+                p.group = mPackageManagerInt.getPermissionGroupTEMP(p.info.group);
+                // Warn for a permission in an unknown group.
+                if (PackageManagerService.DEBUG_PERMISSIONS
+                        && p.info.group != null && p.group == null) {
+                    Slog.i(TAG, "Permission " + p.info.name + " from package "
+                            + p.info.packageName + " in an unknown group " + p.info.group);
+                }
+            }
+
+            synchronized (PermissionManagerService.this.mLock) {
+                if (p.tree) {
+                    final BasePermission bp = BasePermission.createOrUpdate(
+                            mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
+                            mSettings.getAllPermissionTreesLocked(), chatty);
+                    mSettings.putPermissionTreeLocked(p.info.name, bp);
+                } else {
+                    final BasePermission bp = BasePermission.createOrUpdate(
+                            mSettings.getPermissionLocked(p.info.name),
+                            p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
+                    mSettings.putPermissionLocked(p.info.name, bp);
+                }
+            }
+        }
+    }
+
+    private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
+        synchronized (mLock) {
+            int N = pkg.permissions.size();
+            StringBuilder r = null;
+            for (int i=0; i<N; i++) {
+                PackageParser.Permission p = pkg.permissions.get(i);
+                BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
+                if (bp == null) {
+                    bp = mSettings.mPermissionTrees.get(p.info.name);
+                }
+                if (bp != null && bp.isPermission(p)) {
+                    bp.setPermission(null);
+                    if (PackageManagerService.DEBUG_REMOVE && chatty) {
+                        if (r == null) {
+                            r = new StringBuilder(256);
+                        } else {
+                            r.append(' ');
+                        }
+                        r.append(p.info.name);
+                    }
+                }
+                if (p.isAppOp()) {
+                    ArraySet<String> appOpPkgs =
+                            mSettings.mAppOpPermissionPackages.get(p.info.name);
+                    if (appOpPkgs != null) {
+                        appOpPkgs.remove(pkg.packageName);
+                    }
+                }
+            }
+            if (r != null) {
+                if (PackageManagerService.DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
+            }
+
+            N = pkg.requestedPermissions.size();
+            r = null;
+            for (int i=0; i<N; i++) {
+                String perm = pkg.requestedPermissions.get(i);
+                if (mSettings.isPermissionAppOp(perm)) {
+                    ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
+                    if (appOpPkgs != null) {
+                        appOpPkgs.remove(pkg.packageName);
+                        if (appOpPkgs.isEmpty()) {
+                            mSettings.mAppOpPermissionPackages.remove(perm);
+                        }
+                    }
+                }
+            }
+            if (r != null) {
+                if (PackageManagerService.DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
+            }
+        }
+    }
+
+    private boolean addDynamicPermission(
             PermissionInfo info, int callingUid, PermissionCallback callback) {
         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
             throw new SecurityException("Instant apps can't add permissions");
@@ -313,8 +405,7 @@
         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
             throw new SecurityException("Label must be specified in permission");
         }
-        final BasePermission tree = (BasePermission) mPackageManagerInt.enforcePermissionTreeTEMP(
-                info.name, callingUid);
+        final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
         final boolean added;
         final boolean changed;
         synchronized (mLock) {
@@ -341,13 +432,12 @@
         return added;
     }
 
-    private void removePermission(
+    private void removeDynamicPermission(
             String permName, int callingUid, PermissionCallback callback) {
         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
             throw new SecurityException("Instant applications don't have access to this method");
         }
-        final BasePermission tree = (BasePermission) mPackageManagerInt.enforcePermissionTreeTEMP(
-                permName, callingUid);
+        final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
         synchronized (mLock) {
             final BasePermission bp = mSettings.getPermissionLocked(permName);
             if (bp == null) {
@@ -713,7 +803,21 @@
         return runtimePermissionChangedUserIds;
     }
 
-    private int getPermissionFlags(String permName, String packageName, int callingUid, int userId) {
+    private String[] getAppOpPermissionPackages(String permName) {
+        if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+            return null;
+        }
+        synchronized (mLock) {
+            final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
+            if (pkgs == null) {
+                return null;
+            }
+            return pkgs.toArray(new String[pkgs.size()]);
+        }
+    }
+
+    private int getPermissionFlags(
+            String permName, String packageName, int callingUid, int userId) {
         if (!mUserManagerInt.exists(userId)) {
             return 0;
         }
@@ -741,6 +845,96 @@
         return permissionsState.getPermissionFlags(permName, userId);
     }
 
+    private int updatePermissions(String packageName, PackageParser.Package pkgInfo, int flags) {
+        Set<BasePermission> needsUpdate = null;
+        synchronized (mLock) {
+            final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
+            while (it.hasNext()) {
+                final BasePermission bp = it.next();
+                if (bp.isDynamic()) {
+                    bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
+                }
+                if (bp.getSourcePackageSetting() != null) {
+                    if (packageName != null && packageName.equals(bp.getSourcePackageName())
+                        && (pkgInfo == null || !hasPermission(pkgInfo, bp.getName()))) {
+                        Slog.i(TAG, "Removing old permission tree: " + bp.getName()
+                                + " from package " + bp.getSourcePackageName());
+                        flags |= PackageManagerService.UPDATE_PERMISSIONS_ALL;
+                        it.remove();
+                    }
+                    continue;
+                }
+                if (needsUpdate == null) {
+                    needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
+                }
+                needsUpdate.add(bp);
+            }
+        }
+        if (needsUpdate != null) {
+            for (final BasePermission bp : needsUpdate) {
+                final PackageParser.Package pkg =
+                        mPackageManagerInt.getPackage(bp.getSourcePackageName());
+                synchronized (mLock) {
+                    if (pkg != null && pkg.mExtras != null) {
+                        final PackageSetting ps = (PackageSetting) pkg.mExtras;
+                        if (bp.getSourcePackageSetting() == null) {
+                            bp.setSourcePackageSetting(ps);
+                        }
+                        continue;
+                    }
+                    Slog.w(TAG, "Removing dangling permission: " + bp.getName()
+                            + " from package " + bp.getSourcePackageName());
+                    mSettings.removePermissionLocked(bp.getName());
+                }
+            }
+        }
+        return flags;
+    }
+
+    private int updatePermissionTrees(String packageName, PackageParser.Package pkgInfo,
+            int flags) {
+        Set<BasePermission> needsUpdate = null;
+        synchronized (mLock) {
+            final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
+            while (it.hasNext()) {
+                final BasePermission bp = it.next();
+                if (bp.getSourcePackageSetting() != null) {
+                    if (packageName != null && packageName.equals(bp.getSourcePackageName())
+                        && (pkgInfo == null || !hasPermission(pkgInfo, bp.getName()))) {
+                        Slog.i(TAG, "Removing old permission tree: " + bp.getName()
+                                + " from package " + bp.getSourcePackageName());
+                        flags |= PackageManagerService.UPDATE_PERMISSIONS_ALL;
+                        it.remove();
+                    }
+                    continue;
+                }
+                if (needsUpdate == null) {
+                    needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
+                }
+                needsUpdate.add(bp);
+            }
+        }
+        if (needsUpdate != null) {
+            for (final BasePermission bp : needsUpdate) {
+                final PackageParser.Package pkg =
+                        mPackageManagerInt.getPackage(bp.getSourcePackageName());
+                synchronized (mLock) {
+                    if (pkg != null && pkg.mExtras != null) {
+                        final PackageSetting ps = (PackageSetting) pkg.mExtras;
+                        if (bp.getSourcePackageSetting() == null) {
+                            bp.setSourcePackageSetting(ps);
+                        }
+                        continue;
+                    }
+                    Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
+                            + " from package " + bp.getSourcePackageName());
+                    mSettings.removePermissionLocked(bp.getName());
+                }
+            }
+        }
+        return flags;
+    }
+
     private void updatePermissionFlags(String permName, String packageName, int flagMask,
             int flagValues, int callingUid, int userId, PermissionCallback callback) {
         if (!mUserManagerInt.exists(userId)) {
@@ -872,7 +1066,7 @@
 
     private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
         int size = 0;
-        for (BasePermission perm : mSettings.getAllPermissionsLocked()) {
+        for (BasePermission perm : mSettings.mPermissions.values()) {
             size += tree.calculateFootprint(perm);
         }
         return size;
@@ -889,6 +1083,15 @@
         }
     }
 
+    private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
+        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
+            if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Get the first event id for the permission.
      *
@@ -951,14 +1154,22 @@
 
     private class PermissionManagerInternalImpl extends PermissionManagerInternal {
         @Override
-        public boolean addPermission(PermissionInfo info, boolean async, int callingUid,
-                PermissionCallback callback) {
-            return PermissionManagerService.this.addPermission(info, callingUid, callback);
+        public void addAllPermissions(Package pkg, boolean chatty) {
+            PermissionManagerService.this.addAllPermissions(pkg, chatty);
         }
         @Override
-        public void removePermission(String permName, int callingUid,
+        public void removeAllPermissions(Package pkg, boolean chatty) {
+            PermissionManagerService.this.removeAllPermissions(pkg, chatty);
+        }
+        @Override
+        public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
                 PermissionCallback callback) {
-            PermissionManagerService.this.removePermission(permName, callingUid, callback);
+            return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
+        }
+        @Override
+        public void removeDynamicPermission(String permName, int callingUid,
+                PermissionCallback callback) {
+            PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
         }
         @Override
         public void grantRuntimePermission(String permName, String packageName,
@@ -993,12 +1204,26 @@
                     (SharedUserSetting) suSetting, allUserIds);
         }
         @Override
+        public String[] getAppOpPermissionPackages(String permName) {
+            return PermissionManagerService.this.getAppOpPermissionPackages(permName);
+        }
+        @Override
         public int getPermissionFlags(String permName, String packageName, int callingUid,
                 int userId) {
             return PermissionManagerService.this.getPermissionFlags(permName, packageName,
                     callingUid, userId);
         }
         @Override
+        public int updatePermissions(String packageName,
+                PackageParser.Package pkgInfo, int flags) {
+            return PermissionManagerService.this.updatePermissions(packageName, pkgInfo, flags);
+        }
+        @Override
+        public int updatePermissionTrees(String packageName,
+                PackageParser.Package pkgInfo, int flags) {
+            return PermissionManagerService.this.updatePermissionTrees(packageName, pkgInfo, flags);
+        }
+        @Override
         public void updatePermissionFlags(String permName, String packageName, int flagMask,
                 int flagValues, int callingUid, int userId, PermissionCallback callback) {
             PermissionManagerService.this.updatePermissionFlags(
@@ -1038,20 +1263,6 @@
             return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
         }
         @Override
-        public boolean isPermissionInstant(String permName) {
-            synchronized (PermissionManagerService.this.mLock) {
-                final BasePermission bp = mSettings.getPermissionLocked(permName);
-                return (bp != null && bp.isInstant());
-            }
-        }
-        @Override
-        public boolean isPermissionAppOp(String permName) {
-            synchronized (PermissionManagerService.this.mLock) {
-                final BasePermission bp = mSettings.getPermissionLocked(permName);
-                return (bp != null && bp.isAppOp());
-            }
-        }
-        @Override
         public PermissionSettings getPermissionSettings() {
             return mSettings;
         }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionSettings.java b/services/core/java/com/android/server/pm/permission/PermissionSettings.java
index 7a2e5ecc..7d125c9 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionSettings.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionSettings.java
@@ -24,6 +24,7 @@
 import android.util.Log;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.XmlUtils;
 import com.android.server.pm.DumpState;
 import com.android.server.pm.PackageManagerService;
@@ -35,6 +36,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.Collection;
+import java.util.Set;
 
 /**
  * Permissions and other related data. This class is not meant for
@@ -49,8 +51,25 @@
      * All of the permissions known to the system. The mapping is from permission
      * name to permission object.
      */
-    private final ArrayMap<String, BasePermission> mPermissions =
+    @GuardedBy("mLock")
+    final ArrayMap<String, BasePermission> mPermissions =
             new ArrayMap<String, BasePermission>();
+
+    /**
+     * All permission trees known to the system. The mapping is from permission tree
+     * name to permission object.
+     */
+    @GuardedBy("mLock")
+    final ArrayMap<String, BasePermission> mPermissionTrees =
+            new ArrayMap<String, BasePermission>();
+
+    /**
+     * Set of packages that request a particular app op. The mapping is from permission
+     * name to package names.
+     */
+    @GuardedBy("mLock")
+    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
+
     private final Object mLock;
 
     PermissionSettings(@NonNull Context context, @NonNull Object lock) {
@@ -65,15 +84,23 @@
         }
     }
 
+    public void addAppOpPackage(String permName, String packageName) {
+        ArraySet<String> pkgs = mAppOpPermissionPackages.get(permName);
+        if (pkgs == null) {
+            pkgs = new ArraySet<>();
+            mAppOpPermissionPackages.put(permName, pkgs);
+        }
+        pkgs.add(packageName);
+    }
+
     /**
      * Transfers ownership of permissions from one package to another.
      */
-    public void transferPermissions(String origPackageName, String newPackageName,
-            ArrayMap<String, BasePermission> permissionTrees) {
+    public void transferPermissions(String origPackageName, String newPackageName) {
         synchronized (mLock) {
             for (int i=0; i<2; i++) {
                 ArrayMap<String, BasePermission> permissions =
-                        i == 0 ? permissionTrees : mPermissions;
+                        i == 0 ? mPermissionTrees : mPermissions;
                 for (BasePermission bp : permissions.values()) {
                     bp.transfer(origPackageName, newPackageName);
                 }
@@ -94,9 +121,26 @@
         }
     }
 
+    public void readPermissionTrees(XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        synchronized (mLock) {
+            readPermissions(mPermissionTrees, parser);
+        }
+    }
+
     public void writePermissions(XmlSerializer serializer) throws IOException {
-        for (BasePermission bp : mPermissions.values()) {
-            bp.writeLPr(serializer);
+        synchronized (mLock) {
+            for (BasePermission bp : mPermissions.values()) {
+                bp.writeLPr(serializer);
+            }
+        }
+    }
+
+    public void writePermissionTrees(XmlSerializer serializer) throws IOException {
+        synchronized (mLock) {
+            for (BasePermission bp : mPermissionTrees.values()) {
+                bp.writeLPr(serializer);
+            }
         }
     }
 
@@ -128,6 +172,22 @@
                 printedSomething = bp.dumpPermissionsLPr(pw, packageName, permissionNames,
                         externalStorageEnforced, printedSomething, dumpState);
             }
+            if (packageName == null && permissionNames == null) {
+                for (int iperm = 0; iperm<mAppOpPermissionPackages.size(); iperm++) {
+                    if (iperm == 0) {
+                        if (dumpState.onTitlePrinted())
+                            pw.println();
+                        pw.println("AppOp Permissions:");
+                    }
+                    pw.print("  AppOp Permission ");
+                    pw.print(mAppOpPermissionPackages.keyAt(iperm));
+                    pw.println(":");
+                    ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
+                    for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
+                        pw.print("    "); pw.println(pkgs.valueAt(ipkg));
+                    }
+                }
+            }
         }
     }
 
@@ -135,15 +195,58 @@
         return mPermissions.get(permName);
     }
 
+    @Nullable BasePermission getPermissionTreeLocked(@NonNull String permName) {
+        return mPermissionTrees.get(permName);
+    }
+
     void putPermissionLocked(@NonNull String permName, @NonNull BasePermission permission) {
         mPermissions.put(permName, permission);
     }
 
+    void putPermissionTreeLocked(@NonNull String permName, @NonNull BasePermission permission) {
+        mPermissionTrees.put(permName, permission);
+    }
+
     void removePermissionLocked(@NonNull String permName) {
         mPermissions.remove(permName);
     }
 
-    Collection<BasePermission> getAllPermissionsLocked() {
+    void removePermissionTreeLocked(@NonNull String permName) {
+        mPermissionTrees.remove(permName);
+    }
+
+    @NonNull Collection<BasePermission> getAllPermissionsLocked() {
         return mPermissions.values();
     }
+
+    @NonNull Collection<BasePermission> getAllPermissionTreesLocked() {
+        return mPermissionTrees.values();
+    }
+
+    /**
+     * Returns the permission tree for the given permission.
+     * @throws SecurityException If the calling UID is not allowed to add permissions to the
+     * found permission tree.
+     */
+    @Nullable BasePermission enforcePermissionTree(@NonNull String permName, int callingUid) {
+        synchronized (mLock) {
+            return BasePermission.enforcePermissionTree(
+                    mPermissionTrees.values(), permName, callingUid);
+        }
+    }
+
+    public boolean isPermissionInstant(String permName) {
+        synchronized (mLock) {
+            final BasePermission bp = mPermissions.get(permName);
+            return (bp != null && bp.isInstant());
+        }
+    }
+
+    boolean isPermissionAppOp(String permName) {
+        synchronized (mLock) {
+            final BasePermission bp = mPermissions.get(permName);
+            return (bp != null && bp.isAppOp());
+        }
+    }
+
 }
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java
index 342ec4b..7a2e630 100644
--- a/services/core/java/com/android/server/policy/GlobalActions.java
+++ b/services/core/java/com/android/server/policy/GlobalActions.java
@@ -58,6 +58,9 @@
 
     public void showDialog(boolean keyguardShowing, boolean deviceProvisioned) {
         if (DEBUG) Slog.d(TAG, "showDialog " + keyguardShowing + " " + deviceProvisioned);
+        if (mStatusBarInternal.isGlobalActionsDisabled()) {
+            return;
+        }
         mKeyguardShowing = keyguardShowing;
         mDeviceProvisioned = deviceProvisioned;
         mShowing = true;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index db7817e..ceb0ad0 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -18,13 +18,14 @@
 
 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 import static android.app.AppOpsManager.OP_TOAST_WINDOW;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.Context.CONTEXT_RESTRICTED;
 import static android.content.Context.DISPLAY_SERVICE;
@@ -552,7 +553,6 @@
 
     int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
     int mUserRotation = Surface.ROTATION_0;
-    boolean mAccelerometerDefault;
 
     boolean mSupportAutoRotation;
     int mAllowAllRotations = -1;
@@ -707,7 +707,6 @@
     Intent mVrHeadsetHomeIntent;
     boolean mSearchKeyShortcutPending;
     boolean mConsumeSearchKeyUp;
-    boolean mAssistKeyLongPressed;
     boolean mPendingMetaAction;
     boolean mPendingCapsLockToggle;
     int mMetaState;
@@ -838,6 +837,8 @@
     private static final int MSG_DISPATCH_BACK_KEY_TO_AUTOFILL = 24;
     private static final int MSG_SYSTEM_KEY_PRESS = 25;
     private static final int MSG_HANDLE_ALL_APPS = 26;
+    private static final int MSG_LAUNCH_ASSIST = 27;
+    private static final int MSG_LAUNCH_ASSIST_LONG_PRESS = 28;
 
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -879,8 +880,16 @@
                 case MSG_HIDE_BOOT_MESSAGE:
                     handleHideBootMessage();
                     break;
+                case MSG_LAUNCH_ASSIST:
+                    final int deviceId = msg.arg1;
+                    final String hint = (String) msg.obj;
+                    launchAssistAction(hint, deviceId);
+                    break;
+                case MSG_LAUNCH_ASSIST_LONG_PRESS:
+                    launchAssistLongPressAction();
+                    break;
                 case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK:
-                    launchVoiceAssistWithWakeLock(msg.arg1 != 0);
+                    launchVoiceAssistWithWakeLock();
                     break;
                 case MSG_POWER_DELAYED_PRESS:
                     powerPress((Long)msg.obj, msg.arg1 != 0, msg.arg2);
@@ -910,7 +919,7 @@
                     disposeInputConsumer((InputConsumer) msg.obj);
                     break;
                 case MSG_BACK_DELAYED_PRESS:
-                    backMultiPressAction((Long) msg.obj, msg.arg1);
+                    backMultiPressAction(msg.arg1);
                     finishBackKeyPress();
                     break;
                 case MSG_ACCESSIBILITY_SHORTCUT:
@@ -1414,7 +1423,7 @@
         }
     }
 
-    private void backMultiPressAction(long eventTime, int count) {
+    private void backMultiPressAction(int count) {
         if (count >= PANIC_PRESS_BACK_COUNT) {
             switch (mPanicPressOnBackBehavior) {
                 case PANIC_PRESS_BACK_NOTHING:
@@ -1583,7 +1592,7 @@
         }
     }
 
-    private void sleepPress(long eventTime) {
+    private void sleepPress() {
         if (mShortPressOnSleepBehavior == SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME) {
             launchHomeFromHotKey(false /* awakenDreams */, true /*respectKeyguard*/);
         }
@@ -2270,7 +2279,11 @@
 
         // Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
         // http://developer.android.com/guide/practices/screens_support.html#range
-        mForceDefaultOrientation = longSizeDp >= 960 && shortSizeDp >= 720 &&
+        // For car, ignore the dp limitation. It's physically impossible to rotate the car's screen
+        // so if the orientation is forced, we need to respect that no matter what.
+        boolean isCar = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUTOMOTIVE);
+        mForceDefaultOrientation = ((longSizeDp >= 960 && shortSizeDp >= 720) || isCar) &&
                 res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
                 // For debug purposes the next line turns this feature off with:
                 // $ adb shell setprop config.override_forced_orient true
@@ -2844,7 +2857,7 @@
 
         boolean keyguardLocked = isKeyguardLocked();
         boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER
-                && !mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID);
+                && !mWindowManagerInternal.isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
         return (keyguardLocked && !allowWhenLocked && win.getDisplayId() == DEFAULT_DISPLAY)
                 || hideDockDivider;
     }
@@ -3537,44 +3550,11 @@
                 toggleKeyboardShortcutsMenu(event.getDeviceId());
             }
         } else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
-            if (down) {
-                if (repeatCount == 0) {
-                    mAssistKeyLongPressed = false;
-                } else if (repeatCount == 1) {
-                    mAssistKeyLongPressed = true;
-                    if (!keyguardOn) {
-                         launchAssistLongPressAction();
-                    }
-                }
-            } else {
-                if (mAssistKeyLongPressed) {
-                    mAssistKeyLongPressed = false;
-                } else {
-                    if (!keyguardOn) {
-                        launchAssistAction(null, event.getDeviceId());
-                    }
-                }
-            }
+            Slog.wtf(TAG, "KEYCODE_ASSIST should be handled in interceptKeyBeforeQueueing");
             return -1;
         } else if (keyCode == KeyEvent.KEYCODE_VOICE_ASSIST) {
-            if (!down) {
-                Intent voiceIntent;
-                if (!keyguardOn) {
-                    voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
-                } else {
-                    IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
-                            ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
-                    if (dic != null) {
-                        try {
-                            dic.exitIdle("voice-search");
-                        } catch (RemoteException e) {
-                        }
-                    }
-                    voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
-                    voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true);
-                }
-                startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF);
-            }
+            Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in interceptKeyBeforeQueueing");
+            return -1;
         } else if (keyCode == KeyEvent.KEYCODE_SYSRQ) {
             if (down && repeatCount == 0) {
                 mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
@@ -5445,7 +5425,10 @@
 
         boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
                 && attrs.type < FIRST_SYSTEM_WINDOW;
-        final int stackId = win.getStackId();
+        final int windowingMode = win.getWindowingMode();
+        final boolean inFullScreenOrSplitScreenSecondaryWindowingMode =
+                windowingMode == WINDOWING_MODE_FULLSCREEN
+                        || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
         if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi) {
             if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
                 mForceStatusBar = true;
@@ -5464,7 +5447,7 @@
             // represent should be hidden or if we should hide the lockscreen. For attached app
             // windows we defer the decision to the window it is attached to.
             if (appWindow && attached == null) {
-                if (attrs.isFullscreen() && StackId.normallyFullscreenWindows(stackId)) {
+                if (attrs.isFullscreen() && inFullScreenOrSplitScreenSecondaryWindowingMode) {
                     if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
                     mTopFullscreenOpaqueWindowState = win;
                     if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
@@ -5495,7 +5478,7 @@
 
         // Keep track of the window if it's dimming but not necessarily fullscreen.
         if (mTopFullscreenOpaqueOrDimmingWindowState == null && affectsSystemUi
-                && win.isDimming() && StackId.normallyFullscreenWindows(stackId)) {
+                && win.isDimming() && inFullScreenOrSplitScreenSecondaryWindowingMode) {
             mTopFullscreenOpaqueOrDimmingWindowState = win;
         }
 
@@ -5503,7 +5486,7 @@
         // separately, because both the "real fullscreen" opaque window and the one for the docked
         // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.
         if (mTopDockedOpaqueWindowState == null && affectsSystemUi && appWindow && attached == null
-                && attrs.isFullscreen() && stackId == DOCKED_STACK_ID) {
+                && attrs.isFullscreen() && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
             mTopDockedOpaqueWindowState = win;
             if (mTopDockedOpaqueOrDimmingWindowState == null) {
                 mTopDockedOpaqueOrDimmingWindowState = win;
@@ -5513,7 +5496,7 @@
         // Also keep track of any windows that are dimming but not necessarily fullscreen in the
         // docked stack.
         if (mTopDockedOpaqueOrDimmingWindowState == null && affectsSystemUi && win.isDimming()
-                && stackId == DOCKED_STACK_ID) {
+                && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
             mTopDockedOpaqueOrDimmingWindowState = win;
         }
 
@@ -5608,8 +5591,9 @@
                         changes |= FINISH_LAYOUT_REDO_LAYOUT;
                     }
                 } else if (topIsFullscreen
-                        && !mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID)
-                        && !mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID)) {
+                        && !mWindowManagerInternal.isStackVisible(WINDOWING_MODE_FREEFORM)
+                        && !mWindowManagerInternal.isStackVisible(
+                                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
                     if (DEBUG_LAYOUT) Slog.v(TAG, "** HIDING status bar");
                     if (mStatusBarController.setBarShowingLw(false)) {
                         changes |= FINISH_LAYOUT_REDO_LAYOUT;
@@ -6191,7 +6175,7 @@
                     useHapticFeedback = false; // suppress feedback if already non-interactive
                 }
                 if (down) {
-                    sleepPress(event.getEventTime());
+                    sleepPress();
                 } else {
                     sleepRelease(event.getEventTime());
                 }
@@ -6262,18 +6246,30 @@
                 }
                 break;
             }
-            case KeyEvent.KEYCODE_VOICE_ASSIST: {
-                // Only do this if we would otherwise not pass it to the user. In that case,
-                // interceptKeyBeforeDispatching would apply a similar but different policy in
-                // order to invoke voice assist actions. Note that we need to make a copy of the
-                // key event here because the original key event will be recycled when we return.
-                if ((result & ACTION_PASS_TO_USER) == 0 && !down) {
-                    mBroadcastWakeLock.acquire();
-                    Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK,
-                            keyguardActive ? 1 : 0, 0);
+            case KeyEvent.KEYCODE_ASSIST: {
+                final boolean longPressed = event.getRepeatCount() > 0;
+                if (down && longPressed) {
+                    Message msg = mHandler.obtainMessage(MSG_LAUNCH_ASSIST_LONG_PRESS);
                     msg.setAsynchronous(true);
                     msg.sendToTarget();
                 }
+                if (!down && !longPressed) {
+                    Message msg = mHandler.obtainMessage(MSG_LAUNCH_ASSIST, event.getDeviceId(),
+                            0 /* unused */, null /* hint */);
+                    msg.setAsynchronous(true);
+                    msg.sendToTarget();
+                }
+                result &= ~ACTION_PASS_TO_USER;
+                break;
+            }
+            case KeyEvent.KEYCODE_VOICE_ASSIST: {
+                if (!down) {
+                    mBroadcastWakeLock.acquire();
+                    Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK);
+                    msg.setAsynchronous(true);
+                    msg.sendToTarget();
+                }
+                result &= ~ACTION_PASS_TO_USER;
                 break;
             }
             case KeyEvent.KEYCODE_WINDOW: {
@@ -6542,18 +6538,22 @@
         }
     }
 
-    void launchVoiceAssistWithWakeLock(boolean keyguardActive) {
-        IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
-                ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
-        if (dic != null) {
-            try {
-                dic.exitIdle("voice-search");
-            } catch (RemoteException e) {
+    void launchVoiceAssistWithWakeLock() {
+        final Intent voiceIntent;
+        if (!keyguardOn()) {
+            voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
+        } else {
+            IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
+                    ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+            if (dic != null) {
+                try {
+                    dic.exitIdle("voice-search");
+                } catch (RemoteException e) {
+                }
             }
+            voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
+            voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true);
         }
-        Intent voiceIntent =
-            new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
-        voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, keyguardActive);
         startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF);
         mBroadcastWakeLock.release();
     }
@@ -8009,9 +8009,10 @@
     }
 
     private int updateSystemBarsLw(WindowState win, int oldVis, int vis) {
-        final boolean dockedStackVisible = mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID);
+        final boolean dockedStackVisible =
+                mWindowManagerInternal.isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
         final boolean freeformStackVisible =
-                mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID);
+                mWindowManagerInternal.isStackVisible(WINDOWING_MODE_FREEFORM);
         final boolean resizing = mWindowManagerInternal.isDockedDividerResizing();
 
         // We need to force system bars when the docked stack is visible, when the freeform stack
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 853e1b2..515fa39 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -457,8 +457,7 @@
         // First send the high-level shut down broadcast.
         mActionDone = false;
         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
-        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
-                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         mContext.sendOrderedBroadcastAsUser(intent,
                 UserHandle.ALL, null, br, mHandler, 0, null, null);
 
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 05fd248..ca3dd05 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -20,15 +20,25 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.content.IntentFilter;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.IStatsCompanionService;
 import android.os.IStatsManager;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.Slog;
 
+import java.util.ArrayList;
+import java.util.List;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.KernelWakelockReader;
 import com.android.internal.os.KernelWakelockStats;
@@ -53,6 +63,8 @@
 
     private final PendingIntent mAnomalyAlarmIntent;
     private final PendingIntent mPollingAlarmIntent;
+    private final BroadcastReceiver mAppUpdateReceiver;
+    private final BroadcastReceiver mUserUpdateReceiver;
 
     public StatsCompanionService(Context context) {
         super();
@@ -63,8 +75,113 @@
                 new Intent(mContext, AnomalyAlarmReceiver.class), 0);
         mPollingAlarmIntent = PendingIntent.getBroadcast(mContext, 0,
                 new Intent(mContext, PollingAlarmReceiver.class), 0);
+        mAppUpdateReceiver = new AppUpdateReceiver();
+        mUserUpdateReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                synchronized (sStatsdLock) {
+                    sStatsd = fetchStatsdService();
+                    if (sStatsd == null) {
+                        Slog.w(TAG, "Could not access statsd");
+                        return;
+                    }
+                    try {
+                        // Pull the latest state of UID->app name, version mapping.
+                        // Needed since the new user basically has a version of every app.
+                        informAllUidsLocked(context);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Failed to inform statsd that statscompanion is ready", e);
+                        forgetEverything();
+                    }
+                }
+            }
+        };
+        Slog.w(TAG, "Registered receiver for ACTION_PACKAGE_REPLACE AND ADDED.");
     }
 
+    private final static int[] toIntArray(List<Integer> list){
+        int[] ret = new int[list.size()];
+        for(int i = 0;i < ret.length;i++) {
+            ret[i] = list.get(i);
+        }
+        return ret;
+    }
+
+    // Assumes that sStatsdLock is held.
+    private final void informAllUidsLocked(Context context) throws RemoteException {
+        UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        PackageManager pm = context.getPackageManager();
+        final List<UserInfo> users = um.getUsers(true);
+        if (DEBUG) {
+            Slog.w(TAG, "Iterating over "+users.size() + " profiles.");
+        }
+
+        List<Integer> uids = new ArrayList();
+        List<Integer> versions = new ArrayList();
+        List<String> apps = new ArrayList();
+
+        // Add in all the apps for every user/profile.
+        for (UserInfo profile : users) {
+          List<PackageInfo> pi = pm.getInstalledPackagesAsUser(0, profile.id);
+          for (int j = 0; j < pi.size(); j++) {
+              if (pi.get(j).applicationInfo != null) {
+                  uids.add(pi.get(j).applicationInfo.uid);
+                  versions.add(pi.get(j).versionCode);
+                  apps.add(pi.get(j).packageName);
+              }
+          }
+        }
+        sStatsd.informAllUidData(toIntArray(uids), toIntArray(versions), apps.toArray(new
+            String[apps.size()]));
+        if (DEBUG) {
+            Slog.w(TAG, "Sent data for "+uids.size() +" apps");
+        }
+    }
+
+    public final static class AppUpdateReceiver extends BroadcastReceiver  {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Slog.i(TAG, "StatsCompanionService noticed an app was updated.");
+            /**
+             * App updates actually consist of REMOVE, ADD, and then REPLACE broadcasts. To avoid
+             * waste, we ignore the REMOVE and ADD broadcasts that contain the replacing flag.
+             */
+            if (!intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED) &&
+                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                return; // Keep only replacing or normal add and remove.
+            }
+            synchronized (sStatsdLock) {
+                if (sStatsd == null) {
+                    Slog.w(TAG, "Could not access statsd to inform it of anomaly alarm firing");
+                    return;
+                }
+                try {
+                    if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
+                        Bundle b = intent.getExtras();
+                        int uid = b.getInt(Intent.EXTRA_UID);
+                        boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+                        if (!replacing) {
+                            // Don't bother sending an update if we're right about to get another
+                            // intent for the new version that's added.
+                            PackageManager pm = context.getPackageManager();
+                            String app = intent.getData().getSchemeSpecificPart();
+                            sStatsd.informOnePackageRemoved(app, uid);
+                        }
+                    } else {
+                        PackageManager pm = context.getPackageManager();
+                        Bundle b = intent.getExtras();
+                        int uid = b.getInt(Intent.EXTRA_UID);
+                        String app = intent.getData().getSchemeSpecificPart();
+                        PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER);
+                        sStatsd.informOnePackage(app, uid, pi.versionCode);
+                    }
+                } catch (Exception e) {
+                    Slog.w(TAG, "Failed to inform statsd of an app update", e);
+                }
+            }
+        }
+    };
+
     public final static class AnomalyAlarmReceiver extends BroadcastReceiver  {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -161,7 +278,7 @@
         }
     }
 
-    // These values must be kept in sync with cmd/statsd/StatsPuller.h.
+    // These values must be kept in sync with cmd/statsd/StatsPullerManager.h.
     // TODO: pull the constant from stats_events.proto instead
     private static final int PULL_CODE_KERNEL_WAKELOCKS = 20;
 
@@ -275,6 +392,23 @@
                     Slog.e(TAG, "linkToDeath(StatsdDeathRecipient) failed", e);
                     forgetEverything();
                 }
+                // Setup broadcast receiver for updates
+                IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REPLACED);
+                filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+                filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+                filter.addDataScheme("package");
+                mContext.registerReceiverAsUser(mAppUpdateReceiver, UserHandle.ALL, filter, null,
+                    null);
+
+                // Setup receiver for user initialize (which happens once for a new user) and
+                // if a user is removed.
+                filter = new IntentFilter(Intent.ACTION_USER_INITIALIZE);
+                filter.addAction(Intent.ACTION_USER_REMOVED);
+                mContext.registerReceiverAsUser(mUserUpdateReceiver, UserHandle.ALL,
+                    filter, null, null);
+
+                // Pull the latest state of UID->app name, version mapping when statsd starts.
+                informAllUidsLocked(mContext);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Failed to inform statsd that statscompanion is ready", e);
                 forgetEverything();
@@ -293,6 +427,8 @@
     private void forgetEverything() {
         synchronized (sStatsdLock) {
             sStatsd = null;
+            mContext.unregisterReceiver(mAppUpdateReceiver);
+            mContext.unregisterReceiver(mUserUpdateReceiver);
             cancelAnomalyAlarm();
             cancelPollingAlarms();
         }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 0884678..b07fe98 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -77,6 +77,7 @@
 
     void setCurrentUser(int newUserId);
 
+    boolean isGlobalActionsDisabled();
     void setGlobalActionsListener(GlobalActionsListener listener);
     void showGlobalActions();
 
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index bdfbe48..c78a340 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.statusbar;
 
+import static android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS;
+
 import android.app.ActivityThread;
 import android.app.StatusBarManager;
 import android.content.ComponentName;
@@ -363,6 +365,11 @@
         }
 
         @Override
+        public boolean isGlobalActionsDisabled() {
+            return (mDisabled2 & DISABLE2_GLOBAL_ACTIONS) != 0;
+        }
+
+        @Override
         public void setGlobalActionsListener(GlobalActionsListener listener) {
             mGlobalActionListener = listener;
             mGlobalActionListener.onStatusBarConnectedChanged(mBar != null);
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 6117da7..c1607e9 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -1022,20 +1022,6 @@
             }
         }
 
-        @Override
-        public boolean dispatchKeyEventToHdmi(KeyEvent event) throws RemoteException {
-            synchronized (mImplLock) {
-                if (mReleased) {
-                    throw new IllegalStateException("Device already released.");
-                }
-            }
-            if (mInfo.getType() != TvInputHardwareInfo.TV_INPUT_TYPE_HDMI) {
-                return false;
-            }
-            // TODO(hdmi): mHdmiClient.sendKeyEvent(event);
-            return false;
-        }
-
         private boolean startCapture(Surface surface, TvStreamConfig config) {
             synchronized (mImplLock) {
                 if (mReleased) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a1eeff8..5d03493 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -823,7 +823,7 @@
 
         // For freeform windows, we can't freeze the bounds at the moment because this would make
         // the resizing unresponsive.
-        if (task == null || task.inFreeformWorkspace()) {
+        if (task == null || task.inFreeformWindowingMode()) {
             return false;
         }
 
@@ -1310,8 +1310,7 @@
 
                 // Notify the pinned stack upon all windows drawn. If there was an animation in
                 // progress then this signal will resume that animation.
-                final TaskStack pinnedStack =
-                        mDisplayContent.getStack(WINDOWING_MODE_PINNED);
+                final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
                 if (pinnedStack != null) {
                     pinnedStack.onAllWindowsDrawn();
                 }
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index 5c29a0a..d206554 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -18,7 +18,6 @@
 
 import static android.graphics.PixelFormat.OPAQUE;
 import static android.view.SurfaceControl.FX_SURFACE_DIM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -51,14 +50,8 @@
             int w = r-l;
             int h = b-t;
 
-            if (DEBUG_SURFACE_TRACE) {
-                surface = new WindowSurfaceController.SurfaceTrace(session, "BlackSurface("
-                        + l + ", " + t + ")",
-                        w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN);
-            } else {
-                surface = new SurfaceControl(session, "BlackSurface",
-                        w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN);
-            }
+            surface = new SurfaceControl(session, "BlackSurface",
+                    w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN);
 
             surface.setAlpha(1);
             surface.setLayerStack(layerStack);
diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java
index ae41541..85f468b 100644
--- a/services/core/java/com/android/server/wm/CircularDisplayMask.java
+++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -67,14 +66,9 @@
 
         SurfaceControl ctrl = null;
         try {
-            if (DEBUG_SURFACE_TRACE) {
-                ctrl = new WindowSurfaceController.SurfaceTrace(session, "CircularDisplayMask",
-                        mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
-                        SurfaceControl.HIDDEN);
-            } else {
-                ctrl = new SurfaceControl(session, "CircularDisplayMask", mScreenSize.x,
-                        mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
-            }
+            ctrl = new SurfaceControl(session, "CircularDisplayMask", mScreenSize.x,
+                    mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+
             ctrl.setLayerStack(display.getLayerStack());
             ctrl.setLayer(zOrder);
             ctrl.setPosition(0, 0);
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 9e028d3..5bfea98 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -21,7 +21,9 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -182,6 +184,11 @@
         return windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
     }
 
+    public boolean inSplitScreenPrimaryWindowingMode() {
+        return mFullConfiguration.windowConfiguration.getWindowingMode()
+                == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+    }
+
     /**
      * Returns true if this container can be put in either
      * {@link WindowConfiguration#WINDOWING_MODE_SPLIT_SCREEN_PRIMARY} or
@@ -192,6 +199,14 @@
         return mFullConfiguration.windowConfiguration.supportSplitScreenWindowingMode();
     }
 
+    public boolean inPinnedWindowingMode() {
+        return mFullConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_PINNED;
+    }
+
+    public boolean inFreeformWindowingMode() {
+        return mFullConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FREEFORM;
+    }
+
     /** Returns the activity type associated with the the configuration container. */
     /*@WindowConfiguration.ActivityType*/
     public int getActivityType() {
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 708973d..48181d3 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DIM_LAYER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -105,16 +104,10 @@
     private void constructSurface(WindowManagerService service) {
         service.openSurfaceTransaction();
         try {
-            if (DEBUG_SURFACE_TRACE) {
-                mDimSurface = new WindowSurfaceController.SurfaceTrace(service.mFxSession,
-                    "DimSurface",
+            mDimSurface = new SurfaceControl(service.mFxSession, mName,
                     16, 16, PixelFormat.OPAQUE,
                     SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
-            } else {
-                mDimSurface = new SurfaceControl(service.mFxSession, mName,
-                    16, 16, PixelFormat.OPAQUE,
-                    SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
-            }
+
             if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
                     "  DIM " + mDimSurface + ": CREATE");
             mDimSurface.setLayerStack(mDisplayId);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0e68a8f..03fdc96 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -16,10 +16,9 @@
 
 package com.android.server.wm;
 
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
@@ -118,7 +117,7 @@
 
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
-import android.app.ActivityManager.StackId;
+import android.content.pm.PackageManager;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
@@ -297,10 +296,6 @@
     /** Window tokens that are in the process of exiting, but still on screen for animations. */
     final ArrayList<WindowToken> mExitingTokens = new ArrayList<>();
 
-    /** A special TaskStack with id==HOME_STACK_ID that moves to the bottom whenever any TaskStack
-     * (except a future lockscreen TaskStack) moves to the top. */
-    private TaskStack mHomeStack = null;
-
     /** Detect user tapping outside of current focused task bounds .*/
     TaskTapPointerEventListener mTapDetector;
 
@@ -979,8 +974,8 @@
             }
 
             // In the presence of the PINNED stack or System Alert
-            // windows we unforuntately can not seamlessly rotate.
-            if (getStackById(PINNED_STACK_ID) != null) {
+            // windows we unfortunately can not seamlessly rotate.
+            if (hasPinnedStack()) {
                 mayRotateSeamlessly = false;
             }
             for (int i = 0; i < mService.mSessions.size(); i++) {
@@ -1451,20 +1446,31 @@
     }
 
     TaskStack getHomeStack() {
-        if (mHomeStack == null && mDisplayId == DEFAULT_DISPLAY) {
-            Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
-        }
-        return mHomeStack;
+        return mTaskStackContainers.getHomeStack();
     }
 
-    TaskStack getStackById(int stackId) {
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.get(i);
-            if (stack.mStackId == stackId) {
-                return stack;
-            }
-        }
-        return null;
+    /**
+     * @return The primary split-screen stack, but only if it is visible, and {@code null} otherwise.
+     */
+    TaskStack getSplitScreenPrimaryStackStack() {
+        TaskStack stack = mTaskStackContainers.getSplitScreenPrimaryStackStack();
+        return (stack != null && stack.isVisible()) ? stack : null;
+    }
+
+    /**
+     * Like {@link #getSplitScreenPrimaryStackStack}, but also returns the stack if it's currently
+     * not visible.
+     */
+    TaskStack getSplitScreenPrimaryStackStackIgnoringVisibility() {
+        return mTaskStackContainers.getSplitScreenPrimaryStackStack();
+    }
+
+    TaskStack getPinnedStack() {
+        return mTaskStackContainers.getPinnedStack();
+    }
+
+    private boolean hasPinnedStack() {
+        return mTaskStackContainers.getPinnedStack() != null;
     }
 
     /**
@@ -1480,29 +1486,16 @@
      * activity type. Null is no compatible stack on the display.
      */
     TaskStack getStack(int windowingMode, int activityType) {
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.get(i);
-            if (stack.isCompatible(windowingMode, activityType)) {
-                return stack;
-            }
-        }
-        return null;
+        return mTaskStackContainers.getStack(windowingMode, activityType);
     }
 
     @VisibleForTesting
-    int getStackCount() {
-        return mTaskStackContainers.size();
+    TaskStack getTopStack() {
+        return mTaskStackContainers.getTopStack();
     }
 
-    @VisibleForTesting
-    int getStackPosition(int windowingMode, int activityType) {
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.get(i);
-            if (stack.isCompatible(windowingMode, activityType)) {
-                return i;
-            }
-        }
-        return -1;
+    void onStackWindowingModeChanged(TaskStack stack) {
+        mTaskStackContainers.onStackWindowingModeChanged(stack);
     }
 
     @Override
@@ -1523,8 +1516,8 @@
      * bounds were updated.
      */
     void updateStackBoundsAfterConfigChange(@NonNull List<Integer> changedStackList) {
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.get(i);
+        for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
+            final TaskStack stack = mTaskStackContainers.getChildAt(i);
             if (stack.updateBoundsAfterConfigChange()) {
                 changedStackList.add(stack.mStackId);
             }
@@ -1533,7 +1526,7 @@
         // If there was no pinned stack, we still need to notify the controller of the display info
         // update as a result of the config change.  We do this here to consolidate the flow between
         // changes when there is and is not a stack.
-        if (getStack(WINDOWING_MODE_PINNED) == null) {
+        if (!hasPinnedStack()) {
             mPinnedStackControllerLocked.onDisplayInfoChanged();
         }
     }
@@ -1632,8 +1625,8 @@
         mDisplay.getDisplayInfo(mDisplayInfo);
         mDisplay.getMetrics(mDisplayMetrics);
 
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            mTaskStackContainers.get(i).updateDisplayInfo(null);
+        for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
+            mTaskStackContainers.getChildAt(i).updateDisplayInfo(null);
         }
     }
 
@@ -1754,26 +1747,14 @@
         out.set(mContentRect);
     }
 
-    TaskStack addStackToDisplay(int stackId, boolean onTop, StackWindowController controller) {
+    TaskStack createStack(int stackId, boolean onTop, StackWindowController controller) {
         if (DEBUG_STACK) Slog.d(TAG_WM, "Create new stackId=" + stackId + " on displayId="
                 + mDisplayId);
 
-        TaskStack stack = getStackById(stackId);
-        if (stack != null) {
-            // It's already attached to the display...clear mDeferRemoval, set controller, and move
-            // stack to appropriate z-order on display as needed.
-            stack.mDeferRemoval = false;
-            stack.setController(controller);
-            // We're not moving the display to front when we're adding stacks, only when
-            // requested to change the position of stack explicitly.
-            mTaskStackContainers.positionChildAt(onTop ? POSITION_TOP : POSITION_BOTTOM, stack,
-                    false /* includingParents */);
-        } else {
-            stack = new TaskStack(mService, stackId, controller);
-            mTaskStackContainers.addStackToDisplay(stack, onTop);
-        }
+        final TaskStack stack = new TaskStack(mService, stackId, controller);
+        mTaskStackContainers.addStackToDisplay(stack, onTop);
 
-        if (stackId == DOCKED_STACK_ID) {
+        if (stack.inSplitScreenPrimaryWindowingMode()) {
             mDividerControllerLocked.notifyDockedStackExistsChanged(true);
         }
         return stack;
@@ -1790,7 +1771,7 @@
                     + " to its current displayId=" + mDisplayId);
         }
 
-        prevDc.mTaskStackContainers.removeStackFromDisplay(stack);
+        prevDc.mTaskStackContainers.removeChild(stack);
         mTaskStackContainers.addStackToDisplay(stack, onTop);
     }
 
@@ -1824,8 +1805,8 @@
     }
 
     int taskIdFromPoint(int x, int y) {
-        for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mTaskStackContainers.get(stackNdx);
+        for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
             final int taskId = stack.taskIdFromPoint(x, y);
             if (taskId != -1) {
                 return taskId;
@@ -1841,8 +1822,8 @@
     Task findTaskForResizePoint(int x, int y) {
         final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
         mTmpTaskForResizePointSearchResult.reset();
-        for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mTaskStackContainers.get(stackNdx);
+        for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
             if (!stack.getWindowConfiguration().canResizeTask()) {
                 return null;
             }
@@ -1864,8 +1845,8 @@
             mTouchExcludeRegion.set(mBaseDisplayRect);
             final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
             mTmpRect2.setEmpty();
-            for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
-                final TaskStack stack = mTaskStackContainers.get(stackNdx);
+            for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+                final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
                 stack.setTouchExcludeRegion(
                         focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2);
             }
@@ -1896,7 +1877,7 @@
             mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
         }
         // TODO(multi-display): Support docked stacks on secondary displays.
-        if (mDisplayId == DEFAULT_DISPLAY && getDockedStackLocked() != null) {
+        if (mDisplayId == DEFAULT_DISPLAY && getSplitScreenPrimaryStackStack() != null) {
             mDividerControllerLocked.getTouchRegion(mTmpRect);
             mTmpRegion.set(mTmpRect);
             mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
@@ -1913,8 +1894,8 @@
     }
 
     private void resetAnimationBackgroundAnimator() {
-        for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
-            mTaskStackContainers.get(stackNdx).resetAnimationBackgroundAnimator();
+        for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+            mTaskStackContainers.getChildAt(stackNdx).resetAnimationBackgroundAnimator();
         }
     }
 
@@ -1985,8 +1966,8 @@
             float dividerAnimationTarget) {
         boolean updated = false;
 
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.get(i);
+        for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
+            final TaskStack stack = mTaskStackContainers.getChildAt(i);
             if (stack == null || !stack.isAdjustedForIme()) {
                 continue;
             }
@@ -2014,8 +1995,8 @@
 
     boolean clearImeAdjustAnimation() {
         boolean changed = false;
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.get(i);
+        for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
+            final TaskStack stack = mTaskStackContainers.getChildAt(i);
             if (stack != null && stack.isAdjustedForIme()) {
                 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
                 changed  = true;
@@ -2025,8 +2006,8 @@
     }
 
     void beginImeAdjustAnimation() {
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.get(i);
+        for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
+            final TaskStack stack = mTaskStackContainers.getChildAt(i);
             if (stack.isVisible() && stack.isAdjustedForIme()) {
                 stack.beginImeAdjustAnimation();
             }
@@ -2037,7 +2018,7 @@
         final WindowState imeWin = mService.mInputMethodWindow;
         final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
                 && !mDividerControllerLocked.isImeHideRequested();
-        final boolean dockVisible = isStackVisible(DOCKED_STACK_ID);
+        final boolean dockVisible = isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
         final TaskStack imeTargetStack = mService.getImeFocusStackLocked();
         final int imeDockSide = (dockVisible && imeTargetStack != null) ?
                 imeTargetStack.getDockSide() : DOCKED_INVALID;
@@ -2055,8 +2036,8 @@
         // - If IME is not visible, divider is not moved and is normal width.
 
         if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
-            for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-                final TaskStack stack = mTaskStackContainers.get(i);
+            for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
+                final TaskStack stack = mTaskStackContainers.getChildAt(i);
                 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
                 if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)
                         && stack.inSplitScreenWindowingMode()) {
@@ -2068,8 +2049,8 @@
             mDividerControllerLocked.setAdjustedForIme(
                     imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
         } else {
-            for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-                final TaskStack stack = mTaskStackContainers.get(i);
+            for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
+                final TaskStack stack = mTaskStackContainers.getChildAt(i);
                 stack.resetAdjustedForIme(!dockVisible);
             }
             mDividerControllerLocked.setAdjustedForIme(
@@ -2100,8 +2081,8 @@
     }
 
     void prepareFreezingTaskBounds() {
-        for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mTaskStackContainers.get(stackNdx);
+        for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
             stack.prepareFreezingTaskBounds();
         }
     }
@@ -2160,22 +2141,22 @@
         final long token = proto.start(fieldId);
         super.writeToProto(proto, WINDOW_CONTAINER);
         proto.write(ID, mDisplayId);
-        for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mTaskStackContainers.get(stackNdx);
+        for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
             stack.writeToProto(proto, STACKS);
         }
         mDividerControllerLocked.writeToProto(proto, DOCKED_STACK_DIVIDER_CONTROLLER);
         mPinnedStackControllerLocked.writeToProto(proto, PINNED_STACK_CONTROLLER);
-        for (int i = mAboveAppWindowsContainers.size() - 1; i >= 0; --i) {
-            final WindowToken windowToken = mAboveAppWindowsContainers.get(i);
+        for (int i = mAboveAppWindowsContainers.getChildCount() - 1; i >= 0; --i) {
+            final WindowToken windowToken = mAboveAppWindowsContainers.getChildAt(i);
             windowToken.writeToProto(proto, ABOVE_APP_WINDOWS);
         }
-        for (int i = mBelowAppWindowsContainers.size() - 1; i >= 0; --i) {
-            final WindowToken windowToken = mBelowAppWindowsContainers.get(i);
+        for (int i = mBelowAppWindowsContainers.getChildCount() - 1; i >= 0; --i) {
+            final WindowToken windowToken = mBelowAppWindowsContainers.getChildAt(i);
             windowToken.writeToProto(proto, BELOW_APP_WINDOWS);
         }
-        for (int i = mImeWindowsContainers.size() - 1; i >= 0; --i) {
-            final WindowToken windowToken = mImeWindowsContainers.get(i);
+        for (int i = mImeWindowsContainers.getChildCount() - 1; i >= 0; --i) {
+            final WindowToken windowToken = mImeWindowsContainers.getChildAt(i);
             windowToken.writeToProto(proto, IME_WINDOWS);
         }
         proto.write(DPI, mBaseDisplayDensity);
@@ -2221,8 +2202,8 @@
 
         pw.println();
         pw.println(prefix + "Application tokens in top down Z order:");
-        for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mTaskStackContainers.get(stackNdx);
+        for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
             stack.dump(prefix + "  ", pw);
         }
 
@@ -2241,6 +2222,22 @@
         pw.println();
         mDimLayerController.dump(prefix, pw);
         pw.println();
+
+        // Dump stack references
+        final TaskStack homeStack = getHomeStack();
+        if (homeStack != null) {
+            pw.println(prefix + "homeStack=" + homeStack.getName());
+        }
+        final TaskStack pinnedStack = getPinnedStack();
+        if (pinnedStack != null) {
+            pw.println(prefix + "pinnedStack=" + pinnedStack.getName());
+        }
+        final TaskStack splitScreenPrimaryStack = getSplitScreenPrimaryStackStack();
+        if (splitScreenPrimaryStack != null) {
+            pw.println(prefix + "splitScreenPrimaryStack=" + splitScreenPrimaryStack.getName());
+        }
+
+        pw.println();
         mDividerControllerLocked.dump(prefix, pw);
         pw.println();
         mPinnedStackControllerLocked.dump(prefix, pw);
@@ -2260,26 +2257,10 @@
         return "Display " + mDisplayId + " name=\"" + mDisplayInfo.name + "\"";
     }
 
-    /** Checks if stack with provided id is visible on this display. */
-    boolean isStackVisible(int stackId) {
-        final TaskStack stack = getStackById(stackId);
-        return (stack != null && stack.isVisible());
-    }
-
-    /**
-     * @return The docked stack, but only if it is visible, and {@code null} otherwise.
-     */
-    TaskStack getDockedStackLocked() {
-        final TaskStack stack = getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
-        return (stack != null && stack.isVisible()) ? stack : null;
-    }
-
-    /**
-     * Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not
-     * visible.
-     */
-    TaskStack getDockedStackIgnoringVisibility() {
-        return getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+    /** Returns true if the stack in the windowing mode is visible. */
+    boolean isStackVisible(int windowingMode) {
+        final TaskStack stack = getStack(windowingMode);
+        return stack != null && stack.isVisible();
     }
 
     /** Find the visible, touch-deliverable window under the given point */
@@ -3358,14 +3339,6 @@
      */
     static class DisplayChildWindowContainer<E extends WindowContainer> extends WindowContainer<E> {
 
-        int size() {
-            return mChildren.size();
-        }
-
-        E get(int index) {
-            return mChildren.get(index);
-        }
-
         @Override
         boolean fillsParent() {
             return true;
@@ -3383,25 +3356,108 @@
      */
     private final class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {
 
+        // Cached reference to some special stacks we tend to get a lot so we don't need to loop
+        // through the list to find them.
+        private TaskStack mHomeStack = null;
+        private TaskStack mPinnedStack = null;
+        private TaskStack mSplitScreenPrimaryStack = null;
+
+        /**
+         * Returns the topmost stack on the display that is compatible with the input windowing mode
+         * and activity type. Null is no compatible stack on the display.
+         */
+        TaskStack getStack(int windowingMode, int activityType) {
+            if (activityType == ACTIVITY_TYPE_HOME) {
+                return mHomeStack;
+            }
+            if (windowingMode == WINDOWING_MODE_PINNED) {
+                return mPinnedStack;
+            } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+                return mSplitScreenPrimaryStack;
+            }
+            for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
+                final TaskStack stack = mTaskStackContainers.getChildAt(i);
+                if (stack.isCompatible(windowingMode, activityType)) {
+                    return stack;
+                }
+            }
+            return null;
+        }
+
+        @VisibleForTesting
+        TaskStack getTopStack() {
+            return mTaskStackContainers.getChildCount() > 0
+                    ? mTaskStackContainers.getChildAt(mTaskStackContainers.getChildCount() - 1) : null;
+        }
+
+        TaskStack getHomeStack() {
+            if (mHomeStack == null && mDisplayId == DEFAULT_DISPLAY) {
+                Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
+            }
+            return mHomeStack;
+        }
+
+        TaskStack getPinnedStack() {
+            return mPinnedStack;
+        }
+
+        TaskStack getSplitScreenPrimaryStackStack() {
+            return mSplitScreenPrimaryStack;
+        }
+
         /**
          * Adds the stack to this container.
-         * @see WindowManagerService#addStackToDisplay(int, int, boolean)
+         * @see DisplayContent#createStack(int, boolean, StackWindowController)
          */
         void addStackToDisplay(TaskStack stack, boolean onTop) {
-            if (stack.isActivityTypeHome()) {
-                if (mHomeStack != null) {
-                    throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first.");
-                }
-                mHomeStack = stack;
-            }
+            addStackReferenceIfNeeded(stack);
             addChild(stack, onTop);
             stack.onDisplayChanged(DisplayContent.this);
         }
 
-        /** Removes the stack from its container and prepare for changing the parent. */
-        void removeStackFromDisplay(TaskStack stack) {
-            removeChild(stack);
-            stack.onRemovedFromDisplay();
+        void onStackWindowingModeChanged(TaskStack stack) {
+            removeStackReferenceIfNeeded(stack);
+            addStackReferenceIfNeeded(stack);
+            if (stack == mPinnedStack && getTopStack() != stack) {
+                // Looks like this stack changed windowing mode to pinned. Move it to the top.
+                positionChildAt(POSITION_TOP, stack, false /* includingParents */);
+            }
+        }
+
+        private void addStackReferenceIfNeeded(TaskStack stack) {
+            if (stack.isActivityTypeHome()) {
+                if (mHomeStack != null) {
+                    throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
+                            + mHomeStack + " already exist on display=" + this + " stack=" + stack);
+                }
+                mHomeStack = stack;
+            }
+            final int windowingMode = stack.getWindowingMode();
+            if (windowingMode == WINDOWING_MODE_PINNED) {
+                if (mPinnedStack != null) {
+                    throw new IllegalArgumentException("addStackReferenceIfNeeded: pinned stack="
+                            + mPinnedStack + " already exist on display=" + this
+                            + " stack=" + stack);
+                }
+                mPinnedStack = stack;
+            } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+                if (mSplitScreenPrimaryStack != null) {
+                    throw new IllegalArgumentException("addStackReferenceIfNeeded:"
+                            + " split-screen-primary" + " stack=" + mSplitScreenPrimaryStack
+                            + " already exist on display=" + this + " stack=" + stack);
+                }
+                mSplitScreenPrimaryStack = stack;
+            }
+        }
+
+        private void removeStackReferenceIfNeeded(TaskStack stack) {
+            if (stack == mHomeStack) {
+                mHomeStack = null;
+            } else if (stack == mPinnedStack) {
+                mPinnedStack = null;
+            } else if (stack == mSplitScreenPrimaryStack) {
+                mSplitScreenPrimaryStack = null;
+            }
         }
 
         private void addChild(TaskStack stack, boolean toTop) {
@@ -3411,6 +3467,11 @@
             setLayoutNeeded();
         }
 
+        @Override
+        protected void removeChild(TaskStack stack) {
+            super.removeChild(stack);
+            removeStackReferenceIfNeeded(stack);
+        }
 
         @Override
         boolean isOnTop() {
@@ -3453,8 +3514,7 @@
                     : requestedPosition >= topChildPosition;
             int targetPosition = requestedPosition;
 
-            if (toTop && stack.getWindowingMode() != WINDOWING_MODE_PINNED
-                    && getStack(WINDOWING_MODE_PINNED) != null) {
+            if (toTop && stack.getWindowingMode() != WINDOWING_MODE_PINNED && hasPinnedStack()) {
                 // The pinned stack is always the top most stack (always-on-top) when it is present.
                 TaskStack topStack = mChildren.get(topChildPosition);
                 if (topStack.getWindowingMode() != WINDOWING_MODE_PINNED) {
@@ -3556,7 +3616,8 @@
 
         @Override
         int getOrientation() {
-            if (isStackVisible(DOCKED_STACK_ID) || isStackVisible(FREEFORM_WORKSPACE_STACK_ID)) {
+            if (isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
+                    || isStackVisible(WINDOWING_MODE_FREEFORM)) {
                 // Apps and their containers are not allowed to specify an orientation while the
                 // docked or freeform stack is visible...except for the home stack/task if the
                 // docked stack is minimized and it actually set something.
@@ -3571,6 +3632,16 @@
             }
 
             final int orientation = super.getOrientation();
+            boolean isCar = mService.mContext.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_AUTOMOTIVE);
+            if (isCar) {
+                // In a car, you cannot physically rotate the screen, so it doesn't make sense to
+                // allow anything but the default orientation.
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+                        "Forcing UNSPECIFIED orientation in car. Ignoring " + orientation);
+                return SCREEN_ORIENTATION_UNSPECIFIED;
+            }
+
             if (orientation != SCREEN_ORIENTATION_UNSET
                     && orientation != SCREEN_ORIENTATION_BEHIND) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 6f441b9..52526e2 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -16,9 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
@@ -322,7 +319,7 @@
         if (mWindow == null) {
             return;
         }
-        TaskStack stack = mDisplayContent.getDockedStackIgnoringVisibility();
+        TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackStackIgnoringVisibility();
 
         // If the stack is invisible, we policy force hide it in WindowAnimator.shouldForceHide
         final boolean visible = stack != null;
@@ -362,7 +359,7 @@
     }
 
     void positionDockedStackedDivider(Rect frame) {
-        TaskStack stack = mDisplayContent.getDockedStackLocked();
+        TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackStack();
         if (stack == null) {
             // Unfortunately we might end up with still having a divider, even though the underlying
             // stack was already removed. This is because we are on AM thread and the removal of the
@@ -459,7 +456,7 @@
         long animDuration = 0;
         if (animate) {
             final TaskStack stack =
-                    mDisplayContent.getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+                    mDisplayContent.getSplitScreenPrimaryStackStackIgnoringVisibility();
             final long transitionDuration = isAnimationMaximizing()
                     ? mService.mAppTransition.getLastClipRevealTransitionDuration()
                     : DEFAULT_APP_TRANSITION_DURATION;
@@ -513,7 +510,8 @@
     void registerDockedStackListener(IDockedStackListener listener) {
         mDockedStackListeners.register(listener);
         notifyDockedDividerVisibilityChanged(wasVisible());
-        notifyDockedStackExistsChanged(mDisplayContent.getDockedStackIgnoringVisibility() != null);
+        notifyDockedStackExistsChanged(
+                mDisplayContent.getSplitScreenPrimaryStackStackIgnoringVisibility() != null);
         notifyDockedStackMinimizedChanged(mMinimizedDock, false /* animate */,
                 isHomeStackResizable());
         notifyAdjustedForImeChanged(mAdjustedForIme, 0 /* animDuration */);
@@ -532,7 +530,7 @@
         final TaskStack stack = targetWindowingMode != WINDOWING_MODE_UNDEFINED
                 ? mDisplayContent.getStack(targetWindowingMode)
                 : null;
-        final TaskStack dockedStack = mDisplayContent.getDockedStackLocked();
+        final TaskStack dockedStack = mDisplayContent.getSplitScreenPrimaryStackStack();
         boolean visibleAndValid = visible && stack != null && dockedStack != null;
         if (visibleAndValid) {
             stack.getDimBounds(mTmpRect);
@@ -588,7 +586,7 @@
     private boolean containsAppInDockedStack(ArraySet<AppWindowToken> apps) {
         for (int i = apps.size() - 1; i >= 0; i--) {
             final AppWindowToken token = apps.valueAt(i);
-            if (token.getTask() != null && token.getTask().mStack.mStackId == DOCKED_STACK_ID) {
+            if (token.getTask() != null && token.inSplitScreenPrimaryWindowingMode()) {
                 return true;
             }
         }
@@ -600,7 +598,7 @@
     }
 
     private void checkMinimizeChanged(boolean animate) {
-        if (mDisplayContent.getDockedStackIgnoringVisibility() == null) {
+        if (mDisplayContent.getSplitScreenPrimaryStackStackIgnoringVisibility() == null) {
             return;
         }
         final TaskStack homeStack = mDisplayContent.getHomeStack();
@@ -762,7 +760,7 @@
     }
 
     private boolean setMinimizedDockedStack(boolean minimized) {
-        final TaskStack stack = mDisplayContent.getDockedStackIgnoringVisibility();
+        final TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackStackIgnoringVisibility();
         notifyDockedStackMinimizedChanged(minimized, false /* animate */, isHomeStackResizable());
         return stack != null && stack.setAdjustedForMinimizedDock(minimized ? 1f : 0f);
     }
@@ -813,8 +811,7 @@
     }
 
     private boolean animateForMinimizedDockedStack(long now) {
-        final TaskStack stack =
-                mDisplayContent.getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+        final TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackStackIgnoringVisibility();
         if (!mAnimationStarted) {
             mAnimationStarted = true;
             mAnimationStartTime = now;
diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
index 3186d3d..19bd8e9 100644
--- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
+++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -57,14 +56,8 @@
 
         SurfaceControl ctrl = null;
         try {
-            if (DEBUG_SURFACE_TRACE) {
-                ctrl = new WindowSurfaceController.SurfaceTrace(session, "EmulatorDisplayOverlay",
-                        mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
-                        SurfaceControl.HIDDEN);
-            } else {
-                ctrl = new SurfaceControl(session, "EmulatorDisplayOverlay", mScreenSize.x,
-                        mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
-            }
+            ctrl = new SurfaceControl(session, "EmulatorDisplayOverlay", mScreenSize.x,
+                    mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
             ctrl.setLayerStack(display.getLayerStack());
             ctrl.setLayer(zOrder);
             ctrl.setPosition(0, 0);
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 5057f63..238cb9f 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
 import static android.view.WindowManager.INPUT_CONSUMER_PIP;
@@ -650,7 +649,7 @@
             final boolean hasFocus = w == mInputFocus;
             final boolean isVisible = w.isVisibleLw();
 
-            if (w.getStackId() == PINNED_STACK_ID) {
+            if (w.inPinnedWindowingMode()) {
                 if (mAddPipInputConsumerHandle
                         && (inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer)) {
                     // Update the bounds of the Pip input consumer to match the Pinned stack
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index ef31598..365366a 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -417,8 +417,7 @@
                             false /* useCurrentMinEdgeSize */);
                 }
                 final Rect animatingBounds = mTmpAnimatingBoundsRect;
-                final TaskStack pinnedStack =
-                        mDisplayContent.getStack(WINDOWING_MODE_PINNED);
+                final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
                 if (pinnedStack != null) {
                     pinnedStack.getAnimationOrCurrentBounds(animatingBounds);
                 } else {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 7832f5d..fd57470 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -411,17 +411,6 @@
         }
     }
 
-    TaskStack getStackById(int stackId) {
-        for (int i = mChildren.size() - 1; i >= 0; i--) {
-            final DisplayContent dc = mChildren.get(i);
-            final TaskStack stack = dc.getStackById(stackId);
-            if (stack != null) {
-                return stack;
-            }
-        }
-        return null;
-    }
-
     TaskStack getStack(int windowingMode, int activityType) {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final DisplayContent dc = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index d5b6d24..8e99be8 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -24,7 +23,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
 import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;
-import static com.android.server.wm.WindowSurfaceController.SurfaceTrace;
 import static com.android.server.wm.proto.ScreenRotationAnimationProto.ANIMATION_RUNNING;
 import static com.android.server.wm.proto.ScreenRotationAnimationProto.STARTED;
 
@@ -276,17 +274,10 @@
                     flags |= SurfaceControl.SECURE;
                 }
 
-                if (DEBUG_SURFACE_TRACE) {
-                    mSurfaceControl = new SurfaceTrace(session, "ScreenshotSurface",
-                            mWidth, mHeight,
-                            PixelFormat.OPAQUE, flags);
-                    Slog.w(TAG, "ScreenRotationAnimation ctor: displayOffset="
-                            + mOriginalDisplayRect.toShortString());
-                } else {
-                    mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
-                            mWidth, mHeight,
-                            PixelFormat.OPAQUE, flags);
-                }
+                mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
+                        mWidth, mHeight,
+                        PixelFormat.OPAQUE, flags);
+
                 // capture a screenshot into the surface we just created
                 Surface sur = new Surface();
                 sur.copyFrom(mSurfaceControl);
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index c0a4cb7..1fda832 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -16,8 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Handler;
@@ -45,7 +43,7 @@
 public class StackWindowController
         extends WindowContainerController<TaskStack, StackWindowListener> {
 
-    final int mStackId;
+    private final int mStackId;
 
     private final H mHandler;
 
@@ -74,7 +72,7 @@
                         + " to unknown displayId=" + displayId);
             }
 
-            dc.addStackToDisplay(stackId, onTop, this);
+            dc.createStack(stackId, onTop, this);
             getRawBounds(outBounds);
         }
     }
@@ -280,8 +278,9 @@
             if (stack.getWindowConfiguration().tasksAreFloating()) {
                 // Floating tasks should not be resized to the screen's bounds.
 
-                if (mStackId == PINNED_STACK_ID && bounds.width() == mTmpDisplayBounds.width() &&
-                        bounds.height() == mTmpDisplayBounds.height()) {
+                if (stack.inPinnedWindowingMode()
+                        && bounds.width() == mTmpDisplayBounds.width()
+                        && bounds.height() == mTmpDisplayBounds.height()) {
                     // If the bounds we are animating is the same as the fullscreen stack
                     // dimensions, then apply the same inset calculations that we normally do for
                     // the fullscreen stack, without intersecting it with the display bounds
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7e8d130..891d637a 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -17,8 +17,6 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
@@ -213,7 +211,7 @@
         // then we want to preserve our insets so that there will not
         // be a jump in the area covered by system decorations. We rely
         // on the pinned animation to later unset this value.
-        if (stack.mStackId == PINNED_STACK_ID) {
+        if (stack.inPinnedWindowingMode()) {
             mPreserveNonFloatingState = true;
         } else {
             mPreserveNonFloatingState = false;
@@ -421,7 +419,7 @@
         return mFillsParent
                 || !inSplitScreenSecondaryWindowingMode()
                 || displayContent == null
-                || displayContent.getDockedStackIgnoringVisibility() != null;
+                || displayContent.getSplitScreenPrimaryStackStackIgnoringVisibility() != null;
     }
 
     /** Original bounds of the task if applicable, otherwise fullscreen rect. */
@@ -492,7 +490,7 @@
         final boolean dockedResizing = displayContent != null
                 && displayContent.mDividerControllerLocked.isResizing();
         if (useCurrentBounds()) {
-            if (inFreeformWorkspace() && getMaxVisibleBounds(out)) {
+            if (inFreeformWindowingMode() && getMaxVisibleBounds(out)) {
                 return;
             }
 
@@ -598,14 +596,6 @@
         return (tokensCount != 0) && mChildren.get(tokensCount - 1).mShowForAllUsers;
     }
 
-    boolean inFreeformWorkspace() {
-        return mStack != null && mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
-    }
-
-    boolean inPinnedWorkspace() {
-        return mStack != null && mStack.mStackId == PINNED_STACK_ID;
-    }
-
     /**
      * When we are in a floating stack (Freeform, Pinned, ...) we calculate
      * insets differently. However if we are animating to the fullscreen stack
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index c58212c..87de151 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -20,7 +20,6 @@
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.RESIZE_MODE_USER;
 import static android.app.ActivityManager.RESIZE_MODE_USER_FORCED;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -649,7 +648,7 @@
      * shouldn't be shown.
      */
     private int getDimSide(int x) {
-        if (mTask.mStack.mStackId != FREEFORM_WORKSPACE_STACK_ID
+        if (!mTask.mStack.inFreeformWindowingMode()
                 || !mTask.mStack.fillsParent()
                 || mTask.mStack.getConfiguration().orientation != ORIENTATION_LANDSCAPE) {
             return CTRL_NONE;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index bff24f6..54ef065 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -294,7 +294,9 @@
         decorPainter.drawDecors(c, null /* statusBarExcludeFrame */);
         node.end(c);
         final Bitmap hwBitmap = ThreadedRenderer.createHardwareBitmap(node, width, height);
-
+        if (hwBitmap == null) {
+            return null;
+        }
         return new TaskSnapshot(hwBitmap.createGraphicBufferHandle(),
                 topChild.getConfiguration().orientation, mainWindow.mStableInsets,
                 ActivityManager.isLowRamDeviceStatic() /* reduced */, 1.0f /* scale */);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 6527883..d170b6f 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -18,8 +18,6 @@
 
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -296,7 +294,7 @@
         if (mFillsParent
                 || !inSplitScreenSecondaryWindowingMode()
                 || mDisplayContent == null
-                || mDisplayContent.getDockedStackLocked() != null) {
+                || mDisplayContent.getSplitScreenPrimaryStackStack() != null) {
             return true;
         }
         return false;
@@ -409,7 +407,7 @@
             return false;
         }
 
-        if (mStackId == PINNED_STACK_ID) {
+        if (inPinnedWindowingMode()) {
             getAnimationOrCurrentBounds(mTmpRect2);
             boolean updated = mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
                     mTmpRect2, mTmpRect3);
@@ -443,21 +441,19 @@
 
         mTmpRect2.set(mBounds);
         mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
-        switch (mStackId) {
-            case DOCKED_STACK_ID:
-                repositionDockedStackAfterRotation(mTmpRect2);
-                snapDockedStackAfterRotation(mTmpRect2);
-                final int newDockSide = getDockSide(mTmpRect2);
+        if (inSplitScreenPrimaryWindowingMode()) {
+            repositionDockedStackAfterRotation(mTmpRect2);
+            snapDockedStackAfterRotation(mTmpRect2);
+            final int newDockSide = getDockSide(mTmpRect2);
 
-                // Update the dock create mode and clear the dock create bounds, these
-                // might change after a rotation and the original values will be invalid.
-                mService.setDockedStackCreateStateLocked(
-                        (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
-                                ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
-                                : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT,
-                        null);
-                mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
-                break;
+            // Update the dock create mode and clear the dock create bounds, these
+            // might change after a rotation and the original values will be invalid.
+            mService.setDockedStackCreateStateLocked(
+                    (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
+                            ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
+                            : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT,
+                    null);
+            mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
         }
 
         mBoundsAfterRotation.set(mTmpRect2);
@@ -677,6 +673,16 @@
         }
     }
 
+    @Override
+    public void onConfigurationChanged(Configuration newParentConfig) {
+        final int prevWindowingMode = getWindowingMode();
+        super.onConfigurationChanged(newParentConfig);
+        if (mDisplayContent != null && prevWindowingMode != getWindowingMode()) {
+            mDisplayContent.onStackWindowingModeChanged(this);
+        }
+    }
+
+    @Override
     void onDisplayChanged(DisplayContent dc) {
         if (mDisplayContent != null) {
             throw new IllegalStateException("onDisplayChanged: Already attached");
@@ -687,8 +693,8 @@
                 "animation background stackId=" + mStackId);
 
         Rect bounds = null;
-        final TaskStack dockedStack = dc.getDockedStackIgnoringVisibility();
-        if (mStackId == DOCKED_STACK_ID
+        final TaskStack dockedStack = dc.getSplitScreenPrimaryStackStackIgnoringVisibility();
+        if (inSplitScreenPrimaryWindowingMode()
                 || (dockedStack != null && inSplitScreenSecondaryWindowingMode()
                         && !dockedStack.fillsParent())) {
             // The existence of a docked stack affects the size of other static stack created since
@@ -703,10 +709,10 @@
             }
             final boolean dockedOnTopOrLeft = mService.mDockedStackCreateMode
                     == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-            getStackDockedModeBounds(mTmpRect, bounds, mStackId, mTmpRect2,
+            getStackDockedModeBounds(mTmpRect, bounds, mTmpRect2,
                     mDisplayContent.mDividerControllerLocked.getContentWidth(),
                     dockedOnTopOrLeft);
-        } else if (mStackId == PINNED_STACK_ID) {
+        } else if (inPinnedWindowingMode()) {
             // Update the bounds based on any changes to the display info
             getAnimationOrCurrentBounds(mTmpRect2);
             boolean updated = mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
@@ -766,7 +772,8 @@
             return;
         }
 
-        final TaskStack dockedStack = mDisplayContent.getDockedStackIgnoringVisibility();
+        final TaskStack dockedStack =
+                mDisplayContent.getSplitScreenPrimaryStackStackIgnoringVisibility();
         if (dockedStack == null) {
             // Not sure why you are calling this method when there is no docked stack...
             throw new IllegalStateException(
@@ -791,7 +798,7 @@
         mDisplayContent.getLogicalDisplayRect(mTmpRect);
         dockedStack.getRawBounds(mTmpRect2);
         final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT;
-        getStackDockedModeBounds(mTmpRect, outStackBounds, mStackId, mTmpRect2,
+        getStackDockedModeBounds(mTmpRect, outStackBounds, mTmpRect2,
                 mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
 
     }
@@ -800,16 +807,15 @@
      * Outputs the bounds a stack should be given the presence of a docked stack on the display.
      * @param displayRect The bounds of the display the docked stack is on.
      * @param outBounds Output bounds that should be used for the stack.
-     * @param stackId Id of stack we are calculating the bounds for.
      * @param dockedBounds Bounds of the docked stack.
      * @param dockDividerWidth We need to know the width of the divider make to the output bounds
      *                         close to the side of the dock.
      * @param dockOnTopOrLeft If the docked stack is on the top or left side of the screen.
      */
     private void getStackDockedModeBounds(
-            Rect displayRect, Rect outBounds, int stackId, Rect dockedBounds, int dockDividerWidth,
+            Rect displayRect, Rect outBounds, Rect dockedBounds, int dockDividerWidth,
             boolean dockOnTopOrLeft) {
-        final boolean dockedStack = stackId == DOCKED_STACK_ID;
+        final boolean dockedStack = inSplitScreenPrimaryWindowingMode();
         final boolean splitHorizontally = displayRect.width() > displayRect.height();
 
         outBounds.set(displayRect);
@@ -866,7 +872,7 @@
     }
 
     void resetDockedStackToMiddle() {
-        if (mStackId != DOCKED_STACK_ID) {
+        if (inSplitScreenPrimaryWindowingMode()) {
             throw new IllegalStateException("Not a docked stack=" + this);
         }
 
@@ -894,17 +900,12 @@
     }
 
     @Override
-    void removeImmediately() {
-        super.removeImmediately();
+    void onParentSet() {
+        if (getParent() != null || mDisplayContent == null) {
+            return;
+        }
 
-        onRemovedFromDisplay();
-    }
-
-    /**
-     * Removes the stack it from its current parent, so it can be either destroyed completely or
-     * re-parented.
-     */
-    void onRemovedFromDisplay() {
+        // Looks like the stack was removed from the display. Go ahead and clean things up.
         mDisplayContent.mDimLayerController.removeDimLayerUser(this);
         EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
 
@@ -913,7 +914,7 @@
             mAnimationBackgroundSurface = null;
         }
 
-        if (mStackId == DOCKED_STACK_ID) {
+        if (inSplitScreenPrimaryWindowingMode()) {
             mDisplayContent.mDividerControllerLocked.notifyDockedStackExistsChanged(false);
         }
 
@@ -1035,8 +1036,8 @@
     }
 
     boolean shouldIgnoreInput() {
-        return isAdjustedForMinimizedDockedStack() || mStackId == DOCKED_STACK_ID &&
-                isMinimizedDockAndHomeStackResizable();
+        return isAdjustedForMinimizedDockedStack() ||
+                (inSplitScreenPrimaryWindowingMode() && isMinimizedDockAndHomeStackResizable());
     }
 
     /**
@@ -1471,7 +1472,7 @@
                 postExclude.set(mTmpRect);
             }
 
-            final boolean isFreeformed = task.inFreeformWorkspace();
+            final boolean isFreeformed = task.inFreeformWindowingMode();
             if (task != focusedTask || isFreeformed) {
                 if (isFreeformed) {
                     // If the task is freeformed, enlarge the area to account for outside
@@ -1529,7 +1530,7 @@
             }
         }
 
-        if (mStackId == PINNED_STACK_ID) {
+        if (inPinnedWindowingMode()) {
             try {
                 mService.mActivityManager.notifyPinnedStackAnimationStarted();
             } catch (RemoteException e) {
@@ -1561,7 +1562,7 @@
             mService.requestTraversal();
         }
 
-        if (mStackId == PINNED_STACK_ID) {
+        if (inPinnedWindowingMode()) {
             // Update to the final bounds if requested. This is done here instead of in the bounds
             // animator to allow us to coordinate this after we notify the PiP mode changed
 
@@ -1595,7 +1596,7 @@
      *         bounds and we have a deferred PiP mode changed callback set with the animation.
      */
     public boolean deferScheduleMultiWindowModeChanged() {
-        if (mStackId == PINNED_STACK_ID) {
+        if (inPinnedWindowingMode()) {
             return (mBoundsAnimatingRequested || mBoundsAnimating);
         }
         return false;
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 7213c95..629cc86 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -18,7 +18,7 @@
 
 import com.android.internal.util.ToBooleanFunction;
 
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
@@ -447,7 +447,7 @@
 
     private void findWallpaperTarget(DisplayContent dc) {
         mFindResults.reset();
-        if (dc.isStackVisible(FREEFORM_WORKSPACE_STACK_ID)) {
+        if (dc.isStackVisible(WINDOWING_MODE_FREEFORM)) {
             // In freeform mode we set the wallpaper as its own target, so we don't need an
             // additional window to make it visible.
             mFindResults.setUseTopWallpaperAsTarget(true);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 40923c8..1b0825e 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -73,12 +73,12 @@
 
 
     @Override
-    final protected int getChildCount() {
+    protected int getChildCount() {
         return mChildren.size();
     }
 
     @Override
-    final protected E getChildAt(int index) {
+    protected E getChildAt(int index) {
         return mChildren.get(index);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 6d5673e..9d9805a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -60,7 +60,6 @@
     static final boolean DEBUG_SCREENSHOT = false;
     static final boolean DEBUG_BOOT = false;
     static final boolean DEBUG_LAYOUT_REPEATS = false;
-    static final boolean DEBUG_SURFACE_TRACE = false;
     static final boolean DEBUG_WINDOW_TRACE = false;
     static final boolean DEBUG_TASK_MOVEMENT = false;
     static final boolean DEBUG_TASK_POSITIONING = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1fb2188..b133bd4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2384,7 +2384,7 @@
             final Rect insets = new Rect();
             final Rect stableInsets = new Rect();
             Rect surfaceInsets = null;
-            final boolean freeform = win != null && win.inFreeformWorkspace();
+            final boolean freeform = win != null && win.inFreeformWindowingMode();
             if (win != null) {
                 // Containing frame will usually cover the whole screen, including dialog windows.
                 // For freeform workspace windows it will not cover the whole screen and it also
@@ -2794,7 +2794,7 @@
         for (final WindowState win : mWindowMap.values()) {
             final Task task = win.getTask();
             if (task != null && mTmpTaskIds.get(task.mTaskId, -1) != -1
-                    && task.inFreeformWorkspace()) {
+                    && task.inFreeformWindowingMode()) {
                 final AppWindowToken appToken = win.mAppToken;
                 if (appToken != null && appToken.mAppAnimator != null) {
                     appToken.mAppAnimator.startProlongAnimation(scaleUp ?
@@ -3391,7 +3391,8 @@
 
             // Notify whether the docked stack exists for the current user
             final DisplayContent displayContent = getDefaultDisplayContentLocked();
-            final TaskStack stack = displayContent.getDockedStackIgnoringVisibility();
+            final TaskStack stack =
+                    displayContent.getSplitScreenPrimaryStackStackIgnoringVisibility();
             displayContent.mDividerControllerLocked.notifyDockedStackExistsChanged(
                     stack != null && stack.hasTaskForUser(newUserId));
 
@@ -6898,11 +6899,6 @@
                     dumpSessionsLocked(pw, true);
                 }
                 return;
-            } else if ("surfaces".equals(cmd)) {
-                synchronized(mWindowMap) {
-                    WindowSurfaceController.SurfaceTrace.dumpAllSurfaces(pw, null);
-                }
-                return;
             } else if ("displays".equals(cmd) || "d".equals(cmd)) {
                 synchronized(mWindowMap) {
                     mRoot.dumpDisplayContents(pw);
@@ -6967,10 +6963,6 @@
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            WindowSurfaceController.SurfaceTrace.dumpAllSurfaces(pw, dumpAll ?
-                    "-------------------------------------------------------------------------------"
-                    : null);
-            pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
@@ -7132,7 +7124,7 @@
     public int getDockedStackSide() {
         synchronized (mWindowMap) {
             final TaskStack dockedStack = getDefaultDisplayContentLocked()
-                    .getDockedStackIgnoringVisibility();
+                    .getSplitScreenPrimaryStackStackIgnoringVisibility();
             return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide();
         }
     }
@@ -7604,10 +7596,10 @@
         }
 
         @Override
-        public boolean isStackVisible(int stackId) {
+        public boolean isStackVisible(int windowingMode) {
             synchronized (mWindowMap) {
                 final DisplayContent dc = getDefaultDisplayContentLocked();
-                return dc.isStackVisible(stackId);
+                return dc.isStackVisible(windowingMode);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4ff0f39..e171528 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -16,10 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.app.ActivityManager.StackId;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
@@ -83,7 +80,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -815,13 +811,12 @@
             final WindowState imeWin = mService.mInputMethodWindow;
             // IME is up and obscuring this window. Adjust the window position so it is visible.
             if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this) {
-                final int stackId = getStackId();
-                if (stackId == FREEFORM_WORKSPACE_STACK_ID
+                if (inFreeformWindowingMode()
                         && mContainingFrame.bottom > contentFrame.bottom) {
                     // In freeform we want to move the top up directly.
                     // TODO: Investigate why this is contentFrame not parentFrame.
                     mContainingFrame.top -= mContainingFrame.bottom - contentFrame.bottom;
-                } else if (stackId != PINNED_STACK_ID
+                } else if (!inPinnedWindowingMode()
                         && mContainingFrame.bottom > parentFrame.bottom) {
                     // But in docked we want to behave like fullscreen and behave as if the task
                     // were given smaller bounds for the purposes of layout. Skip adjustments for
@@ -898,7 +893,7 @@
             // For pinned workspace the frame isn't limited in any particular
             // way since SystemUI controls the bounds. For freeform however
             // we want to keep things inside the content frame.
-            final Rect limitFrame = task.inPinnedWorkspace() ? mFrame : mContentFrame;
+            final Rect limitFrame = task.inPinnedWindowingMode() ? mFrame : mContentFrame;
             // Keep the frame out of the blocked system area, limit it in size to the content area
             // and make sure that there is always a minimum visible so that the user can drag it
             // into a usable area..
@@ -1210,7 +1205,7 @@
             // application when it has finished drawing.
             if (getOrientationChanging() || dragResizingChanged
                     || isResizedWhileNotDragResizing()) {
-                if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
+                if (DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
                     Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
                             + ", mDrawState=DRAW_PENDING in " + this
                             + ", surfaceController " + winAnimator.mSurfaceController);
@@ -1662,9 +1657,9 @@
             //
             // Anyway we don't need to synchronize position and content updates for these
             // windows since they aren't at the base layer and could be moved around anyway.
-            if (!computeDragResizing() && mAttrs.type == TYPE_BASE_APPLICATION &&
-                    !mWinAnimator.isForceScaled() && !isGoneForLayoutLw() &&
-                    !getTask().inPinnedWorkspace()) {
+            if (!computeDragResizing() && mAttrs.type == TYPE_BASE_APPLICATION
+                    && !mWinAnimator.isForceScaled() && !isGoneForLayoutLw()
+                    && !getTask().inPinnedWindowingMode()) {
                 setResizedWhileNotDragResizing(true);
             }
         }
@@ -2196,12 +2191,6 @@
         }
     }
 
-    // TODO: Strange usage of word workspace here and above.
-    boolean inPinnedWorkspace() {
-        final Task task = getTask();
-        return task != null && task.inPinnedWorkspace();
-    }
-
     void applyAdjustForImeIfNeeded() {
         final Task task = getTask();
         if (task != null && task.mStack != null && task.mStack.isAdjustedForIme()) {
@@ -2235,7 +2224,7 @@
             } else {
                 getVisibleBounds(mTmpRect);
             }
-            if (inFreeformWorkspace()) {
+            if (inFreeformWindowingMode()) {
                 // For freeform windows we the touch region to include the whole surface for the
                 // shadows.
                 final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
@@ -2371,7 +2360,8 @@
                             // just in case they have the divider at an unstable position. Better
                             // also reset drag resizing state, because the owner can't do it
                             // anymore.
-                            final TaskStack stack = dc.getDockedStackIgnoringVisibility();
+                            final TaskStack stack =
+                                    dc.getSplitScreenPrimaryStackStackIgnoringVisibility();
                             if (stack != null) {
                                 stack.resetDockedStackToMiddle();
                             }
@@ -2938,8 +2928,7 @@
         return mTmpRect;
     }
 
-    @Override
-    public int getStackId() {
+    private int getStackId() {
         final TaskStack stack = getStack();
         if (stack == null) {
             return INVALID_STACK_ID;
@@ -2983,11 +2972,6 @@
         }
     }
 
-    boolean inFreeformWorkspace() {
-        final Task task = getTask();
-        return task != null && task.inFreeformWorkspace();
-    }
-
     @Override
     public boolean isInMultiWindowMode() {
         final Task task = getTask();
@@ -3105,7 +3089,7 @@
         // background.
         return (getDisplayContent().mDividerControllerLocked.isResizing()
                         || mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) &&
-                !task.inFreeformWorkspace() && !isGoneForLayoutLw();
+                !task.inFreeformWindowingMode() && !isGoneForLayoutLw();
 
     }
 
@@ -3695,7 +3679,7 @@
 
         // Force the show in the next prepareSurfaceLocked() call.
         mWinAnimator.mLastAlpha = -1;
-        if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) Slog.v(TAG,
+        if (DEBUG_ANIM) Slog.v(TAG,
                 "performShowLocked: mDrawState=HAS_DRAWN in " + this);
         mWinAnimator.mDrawState = HAS_DRAWN;
         mService.scheduleAnimationLocked();
@@ -3756,7 +3740,7 @@
         windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor;
         windowInfo.focused = isFocused();
         Task task = getTask();
-        windowInfo.inPictureInPicture = (task != null) && task.inPinnedWorkspace();
+        windowInfo.inPictureInPicture = (task != null) && task.inPinnedWindowingMode();
 
         if (mIsChildWindow) {
             windowInfo.parentToken = getParentWindow().mClient.asBinder();
@@ -4219,7 +4203,7 @@
         // If a freeform window is animating from a position where it would be cutoff, it would be
         // cutoff during the animation. We don't want that, so for the duration of the animation
         // we ignore the decor cropping and depend on layering to position windows correctly.
-        final boolean cropToDecor = !(inFreeformWorkspace() && isAnimatingLw());
+        final boolean cropToDecor = !(inFreeformWindowingMode() && isAnimatingLw());
         if (cropToDecor) {
             // Intersect with the decor rect, offsetted by window position.
             systemDecorRect.intersect(decorRect.left - left, decorRect.top - top,
@@ -4303,7 +4287,7 @@
         // scale for the animation using the source hint rect
         // (see WindowStateAnimator#setSurfaceBoundariesLocked()).
         if (isDragResizeChanged() || isResizedWhileNotDragResizing()
-                || (surfaceInsetsChanging() && !inPinnedWorkspace())) {
+                || (surfaceInsetsChanging() && !inPinnedWindowingMode())) {
             mLastSurfaceInsets.set(mAttrs.surfaceInsets);
 
             setDragResizing();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 1b7e527..5266903 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -31,7 +31,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
@@ -509,7 +508,7 @@
         boolean layoutNeeded = false;
 
         if (mDrawState == DRAW_PENDING) {
-            if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
+            if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
                 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
                         + mSurfaceController);
             if (DEBUG_STARTING_WINDOW && startingWindow) {
@@ -532,7 +531,7 @@
         if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
             return false;
         }
-        if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
+        if (DEBUG_ANIM) {
             Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceController);
         }
         mDrawState = READY_TO_SHOW;
@@ -1033,7 +1032,7 @@
                 //Slog.i(TAG_WM, "Not applying alpha transform");
             }
 
-            if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV)
+            if ((DEBUG_ANIM || WindowManagerService.localLOGV)
                     && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
                     TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
                     + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null")
@@ -1112,7 +1111,7 @@
      */
     private boolean useFinalClipRect() {
         return (isAnimationSet() && resolveStackClip() == STACK_CLIP_AFTER_ANIM)
-                || mDestroyPreservedSurfaceUponRedraw || mWin.inPinnedWorkspace();
+                || mDestroyPreservedSurfaceUponRedraw || mWin.inPinnedWindowingMode();
     }
 
     /**
@@ -1177,7 +1176,7 @@
             return false;
         }
 
-        if (w.inPinnedWorkspace()) {
+        if (w.inPinnedWindowingMode()) {
             return false;
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 2e1e3f7..d56df55 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -22,7 +22,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -565,262 +564,4 @@
     public String toString() {
         return mSurfaceControl.toString();
     }
-
-    static class SurfaceTrace extends SurfaceControl {
-        private final static String SURFACE_TAG = TAG_WITH_CLASS_NAME ? "SurfaceTrace" : TAG_WM;
-        private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE;
-        final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
-
-        private float mSurfaceTraceAlpha = 0;
-        private int mLayer;
-        private final PointF mPosition = new PointF();
-        private final Point mSize = new Point();
-        private final Rect mWindowCrop = new Rect();
-        private final Rect mFinalCrop = new Rect();
-        private boolean mShown = false;
-        private int mLayerStack;
-        private boolean mIsOpaque;
-        private float mDsdx, mDtdx, mDsdy, mDtdy;
-        private final String mName;
-
-        public SurfaceTrace(SurfaceSession s, String name, int w, int h, int format, int flags,
-                        int windowType, int ownerUid)
-                    throws OutOfResourcesException {
-            super(s, name, w, h, format, flags, windowType, ownerUid);
-            mName = name != null ? name : "Not named";
-            mSize.set(w, h);
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.add(0, this);
-            }
-        }
-
-        public SurfaceTrace(SurfaceSession s,
-                        String name, int w, int h, int format, int flags) {
-            super(s, name, w, h, format, flags);
-            mName = name != null ? name : "Not named";
-            mSize.set(w, h);
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.add(0, this);
-            }
-        }
-
-        @Override
-        public void setAlpha(float alpha) {
-            if (mSurfaceTraceAlpha != alpha) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
-                        ". Called by " + Debug.getCallers(3));
-                mSurfaceTraceAlpha = alpha;
-            }
-            super.setAlpha(alpha);
-        }
-
-        @Override
-        public void setLayer(int zorder) {
-            if (zorder != mLayer) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
-                        + ". Called by " + Debug.getCallers(3));
-                mLayer = zorder;
-            }
-            super.setLayer(zorder);
-
-            synchronized (sSurfaces) {
-                sSurfaces.remove(this);
-                int i;
-                for (i = sSurfaces.size() - 1; i >= 0; i--) {
-                    SurfaceTrace s = sSurfaces.get(i);
-                    if (s.mLayer < zorder) {
-                        break;
-                    }
-                }
-                sSurfaces.add(i + 1, this);
-            }
-        }
-
-        @Override
-        public void setPosition(float x, float y) {
-            if (x != mPosition.x || y != mPosition.y) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mPosition.set(x, y);
-            }
-            super.setPosition(x, y);
-        }
-
-        @Override
-        public void setGeometryAppliesWithResize() {
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setGeometryAppliesWithResize(): OLD: "
-                    + this + ". Called by" + Debug.getCallers(3));
-            super.setGeometryAppliesWithResize();
-        }
-
-        @Override
-        public void setSize(int w, int h) {
-            if (w != mSize.x || h != mSize.y) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mSize.set(w, h);
-            }
-            super.setSize(w, h);
-        }
-
-        @Override
-        public void setWindowCrop(Rect crop) {
-            if (crop != null) {
-                if (!crop.equals(mWindowCrop)) {
-                    if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setWindowCrop("
-                            + crop.toShortString() + "): OLD:" + this + ". Called by "
-                            + Debug.getCallers(3));
-                    mWindowCrop.set(crop);
-                }
-            }
-            super.setWindowCrop(crop);
-        }
-
-        @Override
-        public void setFinalCrop(Rect crop) {
-            if (crop != null) {
-                if (!crop.equals(mFinalCrop)) {
-                    if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setFinalCrop("
-                            + crop.toShortString() + "): OLD:" + this + ". Called by "
-                            + Debug.getCallers(3));
-                    mFinalCrop.set(crop);
-                }
-            }
-            super.setFinalCrop(crop);
-        }
-
-        @Override
-        public void setLayerStack(int layerStack) {
-            if (layerStack != mLayerStack) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mLayerStack = layerStack;
-            }
-            super.setLayerStack(layerStack);
-        }
-
-        @Override
-        public void setOpaque(boolean isOpaque) {
-            if (isOpaque != mIsOpaque) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mIsOpaque = isOpaque;
-            }
-            super.setOpaque(isOpaque);
-        }
-
-        @Override
-        public void setSecure(boolean isSecure) {
-            super.setSecure(isSecure);
-        }
-
-        @Override
-        public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
-            if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
-                        + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
-                        + Debug.getCallers(3));
-                mDsdx = dsdx;
-                mDtdx = dtdx;
-                mDsdy = dsdy;
-                mDtdy = dtdy;
-            }
-            super.setMatrix(dsdx, dtdx, dsdy, dtdy);
-        }
-
-        @Override
-        public void hide() {
-            if (mShown) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
-                        + Debug.getCallers(3));
-                mShown = false;
-            }
-            super.hide();
-        }
-
-        @Override
-        public void show() {
-            if (!mShown) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
-                        + Debug.getCallers(3));
-                mShown = true;
-            }
-            super.show();
-        }
-
-        @Override
-        public void destroy() {
-            super.destroy();
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.remove(this);
-            }
-        }
-
-        @Override
-        public void release() {
-            super.release();
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.remove(this);
-            }
-        }
-
-        @Override
-        public void setTransparentRegionHint(Region region) {
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setTransparentRegionHint(" + region
-                    + "): OLD: " + this + " . Called by " + Debug.getCallers(3));
-            super.setTransparentRegionHint(region);
-        }
-
-        static void dumpAllSurfaces(PrintWriter pw, String header) {
-            synchronized (sSurfaces) {
-                final int N = sSurfaces.size();
-                if (N <= 0) {
-                    return;
-                }
-                if (header != null) {
-                    pw.println(header);
-                }
-                pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
-                for (int i = 0; i < N; i++) {
-                    SurfaceTrace s = sSurfaces.get(i);
-                    pw.print("  Surface #"); pw.print(i); pw.print(": #");
-                            pw.print(Integer.toHexString(System.identityHashCode(s)));
-                            pw.print(" "); pw.println(s.mName);
-                    pw.print("    mLayerStack="); pw.print(s.mLayerStack);
-                            pw.print(" mLayer="); pw.println(s.mLayer);
-                    pw.print("    mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
-                            pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
-                            pw.println(s.mIsOpaque);
-                    pw.print("    mPosition="); pw.print(s.mPosition.x); pw.print(",");
-                            pw.print(s.mPosition.y);
-                            pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
-                            pw.println(s.mSize.y);
-                    pw.print("    mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
-                    pw.print("    mFinalCrop="); s.mFinalCrop.printShortString(pw); pw.println();
-                    pw.print("    Transform: ("); pw.print(s.mDsdx); pw.print(", ");
-                            pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
-                            pw.print(", "); pw.print(s.mDtdy); pw.println(")");
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
-                    + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
-                    + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
-                    + " " + mSize.x + "x" + mSize.y
-                    + " crop=" + mWindowCrop.toShortString()
-                    + " opaque=" + mIsOpaque
-                    + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
-        }
-    }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 92cbd3d..49dd5285 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -125,6 +125,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Future;
 
+import static android.os.IServiceManager.DUMP_PRIORITY_CRITICAL;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 public final class SystemServer {
@@ -824,7 +825,8 @@
             wm = WindowManagerService.main(context, inputManager,
                     mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                     !mFirstBoot, mOnlyCore, new PhoneWindowManager());
-            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
+            ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
+                    DUMP_PRIORITY_CRITICAL);
             ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
             traceEnd();
 
@@ -1640,11 +1642,7 @@
         traceEnd();
 
         traceBeginAndSlog("MakePackageManagerServiceReady");
-        try {
-            mPackageManagerService.systemReady();
-        } catch (Throwable e) {
-            reportWtf("making Package Manager Service ready", e);
-        }
+        mPackageManagerService.systemReady();
         traceEnd();
 
         traceBeginAndSlog("MakeDisplayManagerServiceReady");
diff --git a/services/net/java/android/net/ip/ConnectivityPacketTracker.java b/services/net/java/android/net/ip/ConnectivityPacketTracker.java
index 0230f36..1925c39 100644
--- a/services/net/java/android/net/ip/ConnectivityPacketTracker.java
+++ b/services/net/java/android/net/ip/ConnectivityPacketTracker.java
@@ -25,6 +25,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.PacketSocketAddress;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.LocalLog;
 
@@ -59,11 +60,14 @@
     private static final boolean DBG = false;
     private static final String MARK_START = "--- START ---";
     private static final String MARK_STOP = "--- STOP ---";
+    private static final String MARK_NAMED_START = "--- START (%s) ---";
+    private static final String MARK_NAMED_STOP = "--- STOP (%s) ---";
 
     private final String mTag;
     private final LocalLog mLog;
     private final BlockingSocketReader mPacketListener;
     private boolean mRunning;
+    private String mDisplayName;
 
     public ConnectivityPacketTracker(Handler h, NetworkInterface netif, LocalLog log) {
         final String ifname;
@@ -85,14 +89,16 @@
         mPacketListener = new PacketListener(h, ifindex, hwaddr, mtu);
     }
 
-    public void start() {
+    public void start(String displayName) {
         mRunning = true;
+        mDisplayName = displayName;
         mPacketListener.start();
     }
 
     public void stop() {
         mPacketListener.stop();
         mRunning = false;
+        mDisplayName = null;
     }
 
     private final class PacketListener extends BlockingSocketReader {
@@ -133,16 +139,19 @@
 
         @Override
         protected void onStart() {
-            mLog.log(MARK_START);
+            final String msg = TextUtils.isEmpty(mDisplayName)
+                    ? MARK_START
+                    : String.format(MARK_NAMED_START, mDisplayName);
+            mLog.log(msg);
         }
 
         @Override
         protected void onStop() {
-            if (mRunning) {
-                mLog.log(MARK_STOP);
-            } else {
-                mLog.log(MARK_STOP + " (packet listener stopped unexpectedly)");
-            }
+            String msg = TextUtils.isEmpty(mDisplayName)
+                    ? MARK_STOP
+                    : String.format(MARK_NAMED_STOP, mDisplayName);
+            if (!mRunning) msg += " (packet listener stopped unexpectedly)";
+            mLog.log(msg);
         }
 
         @Override
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index bc07b81..e33f6c9 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -26,6 +26,7 @@
 import android.net.LinkAddress;
 import android.net.LinkProperties.ProvisioningChange;
 import android.net.LinkProperties;
+import android.net.Network;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
 import android.net.StaticIpConfiguration;
@@ -348,6 +349,16 @@
                 return this;
             }
 
+            public Builder withNetwork(Network network) {
+                mConfig.mNetwork = network;
+                return this;
+            }
+
+            public Builder withDisplayName(String displayName) {
+                mConfig.mDisplayName = displayName;
+                return this;
+            }
+
             public ProvisioningConfiguration build() {
                 return new ProvisioningConfiguration(mConfig);
             }
@@ -362,6 +373,8 @@
         /* package */ ApfCapabilities mApfCapabilities;
         /* package */ int mProvisioningTimeoutMs = DEFAULT_TIMEOUT_MS;
         /* package */ int mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
+        /* package */ Network mNetwork = null;
+        /* package */ String mDisplayName = null;
 
         public ProvisioningConfiguration() {} // used by Builder
 
@@ -374,6 +387,9 @@
             mStaticIpConfig = other.mStaticIpConfig;
             mApfCapabilities = other.mApfCapabilities;
             mProvisioningTimeoutMs = other.mProvisioningTimeoutMs;
+            mIPv6AddrGenMode = other.mIPv6AddrGenMode;
+            mNetwork = other.mNetwork;
+            mDisplayName = other.mDisplayName;
         }
 
         @Override
@@ -388,6 +404,8 @@
                     .add("mApfCapabilities: " + mApfCapabilities)
                     .add("mProvisioningTimeoutMs: " + mProvisioningTimeoutMs)
                     .add("mIPv6AddrGenMode: " + mIPv6AddrGenMode)
+                    .add("mNetwork: " + mNetwork)
+                    .add("mDisplayName: " + mDisplayName)
                     .toString();
         }
 
@@ -1441,10 +1459,10 @@
         @Override
         public void enter() {
             // Get the Configuration for ApfFilter from Context
-            boolean filter802_3Frames =
+            final boolean filter802_3Frames =
                     mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames);
 
-            int[] ethTypeBlackList = mContext.getResources().getIntArray(
+            final int[] ethTypeBlackList = mContext.getResources().getIntArray(
                     R.array.config_apfEthTypeBlackList);
 
             mApfFilter = ApfFilter.maybeCreate(mConfiguration.mApfCapabilities, mNetworkInterface,
@@ -1456,7 +1474,7 @@
             }
 
             mPacketTracker = createPacketTracker();
-            if (mPacketTracker != null) mPacketTracker.start();
+            if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);
 
             if (mConfiguration.mEnableIPv6 && !startIPv6()) {
                 doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
@@ -1470,7 +1488,7 @@
                 return;
             }
 
-            InitialConfiguration config = mConfiguration.mInitialConfig;
+            final InitialConfiguration config = mConfiguration.mInitialConfig;
             if ((config != null) && !applyInitialConfig(config)) {
                 // TODO introduce a new IpManagerEvent constant to distinguish this error case.
                 doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java
index 343d237..bbd3d13 100644
--- a/services/net/java/android/net/util/SharedLog.java
+++ b/services/net/java/android/net/util/SharedLog.java
@@ -106,6 +106,10 @@
         record(Category.NONE, msg);
     }
 
+    public void logf(String fmt, Object... args) {
+        log(String.format(fmt, args));
+    }
+
     public void mark(String msg) {
         record(Category.MARK, msg);
     }
diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 9fa1d68..0b4d61f 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -19,6 +19,7 @@
 import static android.app.Notification.GROUP_ALERT_CHILDREN;
 import static android.app.Notification.GROUP_ALERT_SUMMARY;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
 
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
@@ -57,7 +58,13 @@
 import android.service.notification.StatusBarNotification;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Slog;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IAccessibilityManager;
+import android.view.accessibility.IAccessibilityManagerClient;
 
+import com.android.internal.util.IntPair;
 import com.android.server.lights.Light;
 
 import org.junit.Before;
@@ -67,6 +74,8 @@
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -80,6 +89,8 @@
     NotificationManagerService.WorkerHandler mHandler;
     @Mock
     NotificationUsageStats mUsageStats;
+    @Mock
+    IAccessibilityManager mAccessibilityService;
 
     private NotificationManagerService mService;
     private String mPkg = "com.android.server.notification";
@@ -111,17 +122,25 @@
     private static final int MAX_VIBRATION_DELAY = 1000;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
         when(mAudioManager.isAudioFocusExclusive()).thenReturn(false);
         when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer);
         when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
-
         when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
 
-        mService = new NotificationManagerService(getContext());
+        long serviceReturnValue = IntPair.of(
+                AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
+                AccessibilityEvent.TYPES_ALL_MASK);
+        when(mAccessibilityService.addClient(any(), anyInt())).thenReturn(serviceReturnValue);
+        AccessibilityManager accessibilityManager =
+                new AccessibilityManager(Handler.getMain(), mAccessibilityService, 0);
+        verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt());
+        assertTrue(accessibilityManager.isEnabled());
+
+        mService = spy(new NotificationManagerService(getContext()));
         mService.setAudioManager(mAudioManager);
         mService.setVibrator(mVibrator);
         mService.setSystemReady(true);
@@ -130,6 +149,7 @@
         mService.setScreenOn(false);
         mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
         mService.setUsageStats(mUsageStats);
+        mService.setAccessibilityManager(accessibilityManager);
     }
 
     //
@@ -381,6 +401,7 @@
 
         verifyBeepLooped();
         verifyNeverVibrate();
+        verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
     }
 
     @Test
@@ -435,6 +456,7 @@
         r.isUpdate = true;
         mService.buzzBeepBlinkLocked(r);
         verifyBeepLooped();
+        verify(mAccessibilityService, times(2)).sendAccessibilityEvent(any(), anyInt());
     }
 
     @Test
@@ -450,6 +472,7 @@
         // update should not beep
         mService.buzzBeepBlinkLocked(s);
         verifyNeverBeep();
+        verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
     }
 
     @Test
@@ -547,7 +570,7 @@
         mService.mInCall = true;
         mService.buzzBeepBlinkLocked(r);
 
-        //verify(mService, times(1)).playInCallNotification();
+        verify(mService, times(1)).playInCallNotification();
         verifyNeverBeep(); // doesn't play normal beep
     }
 
@@ -842,7 +865,6 @@
         mService.addNotification(r);
 
         mService.buzzBeepBlinkLocked(r);
-
         verifyNeverBeep();
     }
 
@@ -870,7 +892,6 @@
         summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
 
         mService.buzzBeepBlinkLocked(summary);
-
         verify(mUsageStats, never()).isAlertRateLimited(any());
     }
 
@@ -889,6 +910,30 @@
         verifyNeverBeep();
     }
 
+    @Test
+    public void testA11yMinInitialPost() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        r.setImportance(IMPORTANCE_MIN, "");
+        mService.buzzBeepBlinkLocked(r);
+        verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt());
+    }
+
+    @Test
+    public void testA11yQuietInitialPost() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        mService.buzzBeepBlinkLocked(r);
+        verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
+    }
+
+    @Test
+    public void testA11yQuietUpdate() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        mService.buzzBeepBlinkLocked(r);
+        r.isUpdate = true;
+        mService.buzzBeepBlinkLocked(r);
+        verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
+    }
+
     static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
         private final int mRepeatIndex;
 
diff --git a/services/tests/notification/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/notification/src/com/android/server/notification/ZenModeHelperTest.java
new file mode 100644
index 0000000..cbe9650
--- /dev/null
+++ b/services/tests/notification/src/com/android/server/notification/ZenModeHelperTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 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 distriZenbuted 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.server.notification;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.media.AudioAttributes;
+import android.provider.Settings;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ZenModeHelperTest extends NotificationTestCase {
+
+    @Mock ConditionProviders mConditionProviders;
+    private TestableLooper mTestableLooper;
+    private ZenModeHelper mZenModeHelperSpy;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mTestableLooper = TestableLooper.get(this);
+        mZenModeHelperSpy = spy(new ZenModeHelper(getContext(), mTestableLooper.getLooper(),
+                mConditionProviders));
+    }
+
+    @Test
+    public void testZenOff_NoMuteApplied() {
+        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_OFF;
+        assertTrue(mZenModeHelperSpy.mConfig.allowAlarms);
+        mZenModeHelperSpy.applyRestrictions();
+
+        doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyInt());
+        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
+                AudioAttributes.USAGE_ALARM);
+        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
+                AudioAttributes.USAGE_MEDIA);
+    }
+
+    @Test
+    public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() {
+        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        assertTrue(mZenModeHelperSpy.mConfig.allowAlarms);
+        assertTrue(mZenModeHelperSpy.mConfig.allowMediaSystemOther);
+        mZenModeHelperSpy.applyRestrictions();
+        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
+                AudioAttributes.USAGE_ALARM);
+        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
+                AudioAttributes.USAGE_MEDIA);
+    }
+
+    @Test
+    public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() {
+
+        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelperSpy.mConfig.allowAlarms = false;
+        mZenModeHelperSpy.mConfig.allowMediaSystemOther = false;
+        assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
+        assertFalse(mZenModeHelperSpy.mConfig.allowMediaSystemOther);
+        mZenModeHelperSpy.applyRestrictions();
+        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
+                AudioAttributes.USAGE_ALARM);
+
+        // Media is a catch-all that includes games and system sounds
+        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
+                AudioAttributes.USAGE_MEDIA);
+        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
+                AudioAttributes.USAGE_GAME);
+        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
+                AudioAttributes.USAGE_ASSISTANCE_SONIFICATION);
+    }
+}
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index fd83223..6d7d4cb 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -62,6 +62,8 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES += ub-uiautomator
 
+LOCAL_PROGUARD_ENABLED := disabled
+
 include $(BUILD_PACKAGE)
 
 include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/services/tests/servicestests/assets/shortcut/shortcut_api27_backup.xml b/services/tests/servicestests/assets/shortcut/shortcut_api27_backup.xml
new file mode 100644
index 0000000..266ab99
--- /dev/null
+++ b/services/tests/servicestests/assets/shortcut/shortcut_api27_backup.xml
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<user>
+    <launcher-pins package-name="com.android.launcher.1" launcher-user="0">
+        <package-info version="9" last_udpate_time="1230768000000">
+            <signature hash="0X8l7PvMeFf3vr6kaTCL4LJYCUPpbROjrZihNnXEv8I" />
+        </package-info>
+        <package package-name="com.android.test.1" package-user="0">
+            <pin value="s1" />
+        </package>
+    </launcher-pins>
+    <package name="com.android.test.1" call-count="0" last-reset="1506991428317">
+        <package-info version="8" last_udpate_time="1506534668998">
+            <signature hash="zDmdc5A/Bu5pQDKrBTjwVjT/fhzl6OUKwzCocUhPNM8" />
+        </package-info>
+        <shortcut id="s1" activity="com.android.test.1/com.example.android.shortcutsample.Main" title="Leak wakelock" titleid="0" textid="0" dmessageid="0" timestamp="1507674156622" flags="130">
+            <intent intent-base="#Intent;action=com.example.android.shortcutsample.LEAK;launchFlags=0x1000c000;component=com.example.android.shortcutsample/.Main;end" />
+        </shortcut>
+    </package>
+</user>
diff --git a/services/tests/servicestests/res/values/strings.xml b/services/tests/servicestests/res/values/strings.xml
index 121c1de..1253d44 100644
--- a/services/tests/servicestests/res/values/strings.xml
+++ b/services/tests/servicestests/res/values/strings.xml
@@ -21,6 +21,9 @@
     <string name="shortcut_title2"></string>
     <string name="shortcut_text2"></string>
     <string name="shortcut_disabled_message2"></string>
+    <string name="shortcut_title3"></string>
+    <string name="shortcut_text3"></string>
+    <string name="shortcut_disabled_message3"></string>
     <string name="test_account_type1_authenticator_label">AccountManagerService Test Account Type1</string>
     <string name="test_account_type2_authenticator_label">AccountManagerService Test Account Type2</string>
     <string name="test_account_type1">com.android.server.accounts.account_manager_service_test.account.type1</string>
diff --git a/services/tests/servicestests/res/xml/shortcut_5_altalt.xml b/services/tests/servicestests/res/xml/shortcut_5_altalt.xml
new file mode 100644
index 0000000..b17895e
--- /dev/null
+++ b/services/tests/servicestests/res/xml/shortcut_5_altalt.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
+    <shortcut
+        android:shortcutId="ms1"
+        android:enabled="true"
+        android:icon="@drawable/icon1"
+        android:shortcutShortLabel="@string/shortcut_title1"
+        android:shortcutLongLabel="@string/shortcut_text1"
+        android:shortcutDisabledMessage="@string/shortcut_disabled_message1"
+        >
+        <intent
+            android:action="action1"
+            android:data="http://a.b.c/1"
+            >
+        </intent>
+        <categories android:name="android.shortcut.conversation" />
+        <categories android:name="android.shortcut.media" />
+    </shortcut>
+    <shortcut
+        android:shortcutId="ms2"
+        android:enabled="true"
+        android:icon="@drawable/icon2"
+        android:shortcutShortLabel="@string/shortcut_title2"
+        android:shortcutLongLabel="@string/shortcut_text2"
+        android:shortcutDisabledMessage="@string/shortcut_disabled_message2"
+        >
+        <intent
+            android:action="action2"
+            >
+        </intent>
+        <categories android:name="android.shortcut.conversation" />
+    </shortcut>
+    <shortcut
+        android:shortcutId="ms3"
+        android:shortcutShortLabel="@string/shortcut_title1"
+        android:shortcutLongLabel="@string/shortcut_title2"
+        android:shortcutDisabledMessage="@string/shortcut_disabled_message3"
+        >
+        <intent
+            android:action="android.intent.action.VIEW"
+            >
+        </intent>
+    </shortcut>
+    <shortcut
+        android:shortcutId="ms4"
+        android:shortcutShortLabel="@string/shortcut_title2"
+        android:shortcutLongLabel="@string/shortcut_title2"
+        >
+        <intent
+            android:action="android.intent.action.VIEW2"
+            >
+        </intent>
+        <categories />
+        <categories android:name="" />
+        <categories android:name="cat" />
+    </shortcut>
+    <shortcut
+        android:shortcutId="ms5"
+        android:shortcutShortLabel="@string/shortcut_title1"
+        >
+        <intent
+            android:action="action"
+            android:data="http://www/"
+            android:targetPackage="abc"
+            android:targetClass=".xyz"
+            android:mimeType="foo/bar"
+            >
+            <categories android:name="cat1" />
+            <categories android:name="cat2" />
+            <extra android:name="key1" android:value="value1" />
+            <extra android:name="key2" android:value="value2" />
+        </intent>
+    </shortcut>
+</shortcuts>
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityCacheTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityCacheTest.java
index 02f645a..c8dc9ff 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityCacheTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityCacheTest.java
@@ -77,7 +77,6 @@
         mAccessibilityCache.clear();
         AccessibilityInteractionClient.getInstance().clearCache();
         assertEquals(0, numA11yWinInfosInUse.get());
-        assertEquals(0, numA11yNodeInfosInUse.get());
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
index 50824e3..8a54c4e 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
@@ -16,7 +16,6 @@
 
 package com.android.server.accessibility;
 
-import static android.util.ExceptionUtils.propagate;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_MOVE;
 import static android.view.MotionEvent.ACTION_POINTER_DOWN;
@@ -105,8 +104,8 @@
         MagnificationGestureHandler h = new MagnificationGestureHandler(
                 mContext, mMagnificationController,
                 detectTripleTap, detectShortcutTrigger);
-        mHandler = new TestHandler(h.mDetectingStateHandler, mClock);
-        h.mDetectingStateHandler.mHandler = mHandler;
+        mHandler = new TestHandler(h.mDetectingState, mClock);
+        h.mDetectingState.mHandler = mHandler;
         h.setNext(strictMock(EventStreamTransformation.class));
         return h;
     }
@@ -229,7 +228,7 @@
         allowEventDelegation();
         tap();
         // no fast forward
-        verify(mMgh.mNext, times(2)).onMotionEvent(any(), any(), anyInt());
+        verify(mMgh.getNext(), times(2)).onMotionEvent(any(), any(), anyInt());
     }
 
     private void assertTransition(int fromState, Runnable transitionAction, int toState) {
@@ -250,7 +249,7 @@
     }
 
     private void allowEventDelegation() {
-        doNothing().when(mMgh.mNext).onMotionEvent(any(), any(), anyInt());
+        doNothing().when(mMgh.getNext()).onMotionEvent(any(), any(), anyInt());
     }
 
     private void fastForward1sec() {
@@ -272,7 +271,7 @@
 
             case STATE_IDLE: {
                 check(tapCount() < 2, state);
-                check(!mMgh.mShortcutTriggered, state);
+                check(!mMgh.mDetectingState.mShortcutTriggered, state);
                 check(!isZoomed(), state);
             } break;
             case STATE_ZOOMED: {
@@ -288,28 +287,28 @@
                 check(tapCount() == 2, state);
             } break;
             case STATE_DRAGGING: {
-                check(mMgh.mCurrentState == MagnificationGestureHandler.STATE_VIEWPORT_DRAGGING,
+                check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
                         state);
-                check(mMgh.mViewportDraggingStateHandler.mZoomedInBeforeDrag, state);
+                check(mMgh.mViewportDraggingState.mZoomedInBeforeDrag, state);
             } break;
             case STATE_DRAGGING_TMP: {
-                check(mMgh.mCurrentState == MagnificationGestureHandler.STATE_VIEWPORT_DRAGGING,
+                check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
                         state);
-                check(!mMgh.mViewportDraggingStateHandler.mZoomedInBeforeDrag, state);
+                check(!mMgh.mViewportDraggingState.mZoomedInBeforeDrag, state);
             } break;
             case STATE_SHORTCUT_TRIGGERED: {
-                check(mMgh.mShortcutTriggered, state);
+                check(mMgh.mDetectingState.mShortcutTriggered, state);
                 check(!isZoomed(), state);
             } break;
             case STATE_PANNING: {
-                check(mMgh.mCurrentState == MagnificationGestureHandler.STATE_PANNING_SCALING,
+                check(mMgh.mCurrentState == mMgh.mPanningScalingState,
                         state);
-                check(!mMgh.mPanningScalingStateHandler.mScaling, state);
+                check(!mMgh.mPanningScalingState.mScaling, state);
             } break;
             case STATE_SCALING_AND_PANNING: {
-                check(mMgh.mCurrentState == MagnificationGestureHandler.STATE_PANNING_SCALING,
+                check(mMgh.mCurrentState == mMgh.mPanningScalingState,
                         state);
-                check(mMgh.mPanningScalingStateHandler.mScaling, state);
+                check(mMgh.mPanningScalingState.mScaling, state);
             } break;
             default: throw new IllegalArgumentException("Illegal state: " + state);
         }
@@ -432,7 +431,7 @@
     }
 
     private int tapCount() {
-        return mMgh.mDetectingStateHandler.tapCount();
+        return mMgh.mDetectingState.tapCount();
     }
 
     private static String stateToString(int state) {
@@ -492,7 +491,7 @@
     }
 
     private long defaultDownTime() {
-        MotionEvent lastDown = mMgh.mDetectingStateHandler.mLastDown;
+        MotionEvent lastDown = mMgh.mDetectingState.mLastDown;
         return lastDown == null ? mClock.now() - 1 : lastDown.getDownTime();
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index 855b82c..026abce 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -20,7 +20,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 
-import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
@@ -61,7 +60,7 @@
     public void setUp() throws Exception {
         super.setUp();
         mService = createActivityManagerService();
-        mStarter = new ActivityStarter(mService, mService.mStackSupervisor);
+        mStarter = new ActivityStarter(mService);
     }
 
     @Test
@@ -83,7 +82,7 @@
         assertTrue(task2.getStack() instanceof PinnedActivityStack);
         mStarter.updateBounds(task2, bounds);
 
-        verify(mService, times(1)).resizeStack(eq(ActivityManager.StackId.PINNED_STACK_ID),
+        verify(mService, times(1)).resizeStack(eq(task2.getStack().mStackId),
                 eq(bounds), anyBoolean(), anyBoolean(), anyBoolean(), anyInt());
 
         // In the case of no animation, the stack and task bounds should be set immediately.
@@ -94,4 +93,4 @@
             assertEquals(task2.mBounds, null);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 1f6dda1..20077f3 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -55,10 +55,6 @@
     private final Context mContext = InstrumentationRegistry.getContext();
     private HandlerThread mHandlerThread;
 
-    // Grabbing an instance of {@link WindowManagerService} creates it if not present so this must
-    // be called at before any tests.
-    private final WindowManagerService mWms = WindowTestUtils.getWindowManagerService(mContext);
-
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -107,15 +103,21 @@
 
     protected static TaskRecord createTask(ActivityStackSupervisor supervisor,
             ComponentName component, ActivityStack stack) {
+        return createTask(supervisor, component, 0 /* flags */, 0 /* taskId */, stack);
+    }
+
+    protected static TaskRecord createTask(ActivityStackSupervisor supervisor,
+            ComponentName component, int flags, int taskId, ActivityStack stack) {
         final ActivityInfo aInfo = new ActivityInfo();
         aInfo.applicationInfo = new ApplicationInfo();
         aInfo.applicationInfo.packageName = component.getPackageName();
 
         Intent intent = new Intent();
         intent.setComponent(component);
+        intent.setFlags(flags);
 
-        final TaskRecord task = new TaskRecord(supervisor.mService, 0, aInfo, intent /*intent*/,
-                null /*_taskDescription*/);
+        final TaskRecord task = new TaskRecord(supervisor.mService, taskId, aInfo,
+                intent /*intent*/, null /*_taskDescription*/);
         supervisor.setFocusStackUnchecked("test", stack);
         stack.addTask(task, true, "creating test task");
         task.setStack(stack);
@@ -136,7 +138,7 @@
             mSupportsSplitScreenMultiWindow = true;
             mSupportsFreeformWindowManagement = true;
             mSupportsPictureInPicture = true;
-            mWindowManager = WindowTestUtils.getWindowManagerService(context);
+            mWindowManager = WindowTestUtils.getMockWindowManagerService();
         }
 
         @Override
diff --git a/services/tests/servicestests/src/com/android/server/am/LaunchBoundsTests.java b/services/tests/servicestests/src/com/android/server/am/LaunchBoundsTests.java
new file mode 100644
index 0000000..e6d6831
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/LaunchBoundsTests.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2017 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.server.am;
+
+import android.content.ComponentName;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.WindowLayout;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import android.view.Display;
+import android.view.Gravity;
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.invocation.InvocationOnMock;
+
+import java.util.ArrayList;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doAnswer;
+import static org.junit.Assert.assertEquals;
+
+
+/**
+ * Tests for exercising resizing bounds.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.am.LaunchBoundsTests
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class LaunchBoundsTests extends ActivityTestsBase {
+    private final ComponentName testActivityComponent =
+            ComponentName.unflattenFromString("com.foo/.BarActivity");
+    private final ComponentName testActivityComponent2 =
+            ComponentName.unflattenFromString("com.foo/.BarActivity2");
+
+    private final static int STACK_WIDTH = 100;
+    private final static int STACK_HEIGHT = 200;
+
+    private final static Rect STACK_BOUNDS = new Rect(0, 0, STACK_WIDTH, STACK_HEIGHT);
+
+    private ActivityManagerService mService;
+    private ActivityStack mStack;
+    private TaskRecord mTask;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mService = createActivityManagerService();
+        mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        mStack.requestResize(STACK_BOUNDS);
+
+        // We must create the task after resizing to make sure it does not inherit the stack
+        // dimensions on resize.
+        mTask = createTask(mService.mStackSupervisor, testActivityComponent, mStack);
+    }
+
+    /**
+     * Ensures that the setup bounds are set as expected with the stack bounds set and the task
+     * bounds still {@code null}.
+     * @throws Exception
+     */
+    @Test
+    public void testInitialBounds() throws Exception {
+        assertEquals(mStack.mBounds, STACK_BOUNDS);
+        assertEquals(mTask.mBounds, null);
+    }
+
+    /**
+     * Ensures that a task positioned with no {@link WindowLayout} receives the default launch
+     * position.
+     * @throws Exception
+     */
+    @Test
+    public void testLaunchNoWindowLayout() throws Exception {
+        final Rect expectedTaskBounds = getDefaultBounds(Gravity.NO_GRAVITY);
+
+        mStack.layoutTaskInStack(mTask, null);
+
+        // We expect the task to be placed in the middle of the screen with margins applied.
+        assertEquals(mTask.mBounds, expectedTaskBounds);
+    }
+
+    /**
+     * Ensures that a task positioned with an empty {@link WindowLayout} receives the default launch
+     * position.
+     * @throws Exception
+     */
+    @Test
+    public void testlaunchEmptyWindowLayout() throws Exception {
+        final Rect expectedTaskBounds = getDefaultBounds(Gravity.NO_GRAVITY);
+
+        WindowLayout layout = new WindowLayout(0, 0, 0, 0, 0, 0, 0);
+        mStack.layoutTaskInStack(mTask, layout);
+        assertEquals(mTask.mBounds, expectedTaskBounds);
+    }
+
+    /**
+     * Ensures that a task positioned with a {@link WindowLayout} gravity specified is positioned
+     * according to specification.
+     * @throws Exception
+     */
+    @Test
+    public void testlaunchWindowLayoutGravity() throws Exception {
+        // Unspecified gravity should be ignored
+        testGravity(Gravity.NO_GRAVITY);
+
+        // Unsupported gravity should be ignored
+        testGravity(Gravity.LEFT);
+        testGravity(Gravity.RIGHT);
+
+        // Test defaults for vertical gravities
+        testGravity(Gravity.TOP);
+        testGravity(Gravity.BOTTOM);
+
+        // Test corners
+        testGravity(Gravity.TOP | Gravity.LEFT);
+        testGravity(Gravity.TOP | Gravity.RIGHT);
+        testGravity(Gravity.BOTTOM | Gravity.LEFT);
+        testGravity(Gravity.BOTTOM | Gravity.RIGHT);
+    }
+
+    private void testGravity(int gravity) {
+        final WindowLayout gravityLayout = new WindowLayout(0, 0, 0, 0, gravity, 0, 0);
+        mStack.layoutTaskInStack(mTask, gravityLayout);
+        assertEquals(mTask.mBounds, getDefaultBounds(gravity));
+    }
+
+    /**
+     * Ensures that a task which causes a conflict with another task when positioned is adjusted as
+     * expected.
+     * @throws Exception
+     */
+    @Test
+    public void testLaunchWindowCenterConflict() throws Exception {
+        testConflict(Gravity.NO_GRAVITY);
+        testConflict(Gravity.TOP);
+        testConflict(Gravity.BOTTOM);
+        testConflict(Gravity.TOP | Gravity.LEFT);
+        testConflict(Gravity.TOP | Gravity.RIGHT);
+        testConflict(Gravity.BOTTOM | Gravity.LEFT);
+        testConflict(Gravity.BOTTOM | Gravity.RIGHT);
+    }
+
+    private void testConflict(int gravity) {
+        final WindowLayout layout = new WindowLayout(0, 0, 0, 0, gravity, 0, 0);
+
+        // layout first task
+        mStack.layoutTaskInStack(mTask, layout /*windowLayout*/);
+
+        // Second task will be laid out on top of the first so starting bounds is the same.
+        final Rect expectedBounds = new Rect(mTask.mBounds);
+
+        ActivityRecord activity = null;
+        TaskRecord secondTask = null;
+
+        // wrap with try/finally to ensure cleanup of activity/stack.
+        try {
+            // empty tasks are ignored in conflicts
+            activity = createActivity(mService, testActivityComponent, mTask);
+
+            // Create secondary task
+            secondTask = createTask(mService.mStackSupervisor, testActivityComponent,
+                    mStack);
+
+            // layout second task
+            mStack.layoutTaskInStack(secondTask, layout /*windowLayout*/);
+
+            if ((gravity & (Gravity.TOP | Gravity.RIGHT)) == (Gravity.TOP | Gravity.RIGHT)
+                    || (gravity & (Gravity.BOTTOM | Gravity.RIGHT))
+                    == (Gravity.BOTTOM | Gravity.RIGHT)) {
+                expectedBounds.offset(-LaunchingTaskPositioner.getHorizontalStep(mStack.mBounds),
+                        0);
+            } else if ((gravity & Gravity.TOP) == Gravity.TOP
+                    || (gravity & Gravity.BOTTOM) == Gravity.BOTTOM) {
+                expectedBounds.offset(LaunchingTaskPositioner.getHorizontalStep(mStack.mBounds), 0);
+            } else {
+                expectedBounds.offset(LaunchingTaskPositioner.getHorizontalStep(mStack.mBounds),
+                        LaunchingTaskPositioner.getVerticalStep(mStack.mBounds));
+            }
+
+            assertEquals(secondTask.mBounds, expectedBounds);
+        } finally {
+            // Remove task and activity to prevent influencing future tests
+            if (activity != null) {
+                mTask.removeActivity(activity);
+            }
+
+            if (secondTask != null) {
+                mStack.removeTask(secondTask, "cleanup", ActivityStack.REMOVE_TASK_MODE_DESTROYING);
+            }
+        }
+    }
+
+    private Rect getDefaultBounds(int gravity) {
+        final Rect bounds = new Rect();
+        bounds.set(mStack.mBounds);
+
+        final int verticalInset = LaunchingTaskPositioner.getFreeformStartTop(mStack.mBounds);
+        final int horizontalInset = LaunchingTaskPositioner.getFreeformStartLeft(mStack.mBounds);
+
+        bounds.inset(horizontalInset, verticalInset);
+
+        if ((gravity & (Gravity.TOP | Gravity.RIGHT)) == (Gravity.TOP | Gravity.RIGHT)) {
+            bounds.offsetTo(horizontalInset * 2, 0);
+        } else if ((gravity & Gravity.TOP) == Gravity.TOP) {
+            bounds.offsetTo(0, 0);
+        } else if ((gravity & (Gravity.BOTTOM | Gravity.RIGHT))
+                == (Gravity.BOTTOM | Gravity.RIGHT)) {
+            bounds.offsetTo(horizontalInset * 2, verticalInset * 2);
+        } else if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) {
+            bounds.offsetTo(0, verticalInset * 2);
+        }
+
+        return bounds;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
new file mode 100644
index 0000000..e607228
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2017 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.server.am;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.Debug;
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.MutableLong;
+import android.util.SparseBooleanArray;
+
+import com.android.server.am.RecentTasks.Callbacks;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RecentTasksTest extends ActivityTestsBase {
+    private static final int TEST_USER_0_ID = 0;
+    private static final int TEST_USER_1_ID = 10;
+    private static final int TEST_QUIET_USER_ID = 20;
+    private static final UserInfo DEFAULT_USER_INFO = new UserInfo();
+    private static final UserInfo QUIET_USER_INFO = new UserInfo();
+    private static int LAST_TASK_ID = 1;
+
+    private Context mContext = InstrumentationRegistry.getContext();
+    private ActivityManagerService mService;
+    private ActivityStack mStack;
+    private TestTaskPersister mTaskPersister;
+    private RecentTasks mRecentTasks;
+
+    private static ArrayList<TaskRecord> mTasks = new ArrayList<>();
+    private static ArrayList<TaskRecord> mSameDocumentTasks = new ArrayList<>();
+
+    private CallbacksRecorder mCallbacksRecorder;
+
+    class TestUserController extends UserController {
+        TestUserController(ActivityManagerService service) {
+            super(service);
+        }
+
+        @Override
+        int[] getCurrentProfileIds() {
+            return new int[] { TEST_USER_0_ID, TEST_QUIET_USER_ID };
+        }
+
+        @Override
+        UserInfo getUserInfo(int userId) {
+            switch (userId) {
+                case TEST_USER_0_ID:
+                case TEST_USER_1_ID:
+                    return DEFAULT_USER_INFO;
+                case TEST_QUIET_USER_ID:
+                    return QUIET_USER_INFO;
+            }
+            return null;
+        }
+    }
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mService = createActivityManagerService();
+        mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        mTaskPersister = new TestTaskPersister(mContext.getFilesDir());
+        mRecentTasks = new RecentTasks(mService, mTaskPersister, new TestUserController(mService));
+        mRecentTasks.loadParametersFromResources(mContext.getResources());
+        mCallbacksRecorder = new CallbacksRecorder();
+        mRecentTasks.registerCallback(mCallbacksRecorder);
+        QUIET_USER_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_QUIET_MODE;
+
+        mTasks.add(createTask(".Task1"));
+        mTasks.add(createTask(".Task2"));
+        mTasks.add(createTask(".Task3"));
+        mTasks.add(createTask(".Task4"));
+        mTasks.add(createTask(".Task5"));
+
+        mSameDocumentTasks.add(createDocumentTask(".DocumentTask1", null /* affinity */));
+        mSameDocumentTasks.add(createDocumentTask(".DocumentTask1", null /* affinity */));
+    }
+
+    @Test
+    public void testCallbacks() throws Exception {
+        // Add some tasks
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.add(mTasks.get(1));
+        assertTrue(mCallbacksRecorder.added.contains(mTasks.get(0))
+                && mCallbacksRecorder.added.contains(mTasks.get(1)));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+        mCallbacksRecorder.clear();
+
+        // Remove some tasks
+        mRecentTasks.remove(mTasks.get(0));
+        mRecentTasks.remove(mTasks.get(1));
+        assertTrue(mCallbacksRecorder.added.isEmpty());
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.contains(mTasks.get(0)));
+        assertTrue(mCallbacksRecorder.removed.contains(mTasks.get(1)));
+        mCallbacksRecorder.clear();
+
+        // Add a task which will trigger the trimming of another
+        TaskRecord documentTask1 = createDocumentTask(".DocumentTask1", null /* affinity */);
+        documentTask1.maxRecents = 1;
+        TaskRecord documentTask2 = createDocumentTask(".DocumentTask1", null /* affinity */);
+        mRecentTasks.add(documentTask1);
+        mRecentTasks.add(documentTask2);
+        assertTrue(mCallbacksRecorder.added.contains(documentTask1));
+        assertTrue(mCallbacksRecorder.added.contains(documentTask2));
+        assertTrue(mCallbacksRecorder.trimmed.contains(documentTask1));
+        assertTrue(mCallbacksRecorder.removed.contains(documentTask1));
+        mCallbacksRecorder.clear();
+
+        // Remove the callback, ensure we don't get any calls
+        mRecentTasks.unregisterCallback(mCallbacksRecorder);
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.remove(mTasks.get(0));
+        assertTrue(mCallbacksRecorder.added.isEmpty());
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+    }
+
+    @Test
+    public void testUsersTasks() throws Exception {
+        // Setup some tasks for the users
+        mTaskPersister.userTaskIdsOverride = new SparseBooleanArray();
+        mTaskPersister.userTaskIdsOverride.put(1, true);
+        mTaskPersister.userTaskIdsOverride.put(2, true);
+        mTaskPersister.userTasksOverride = new ArrayList<>();
+        mTaskPersister.userTasksOverride.add(createTask(".UserTask1"));
+        mTaskPersister.userTasksOverride.add(createTask(".UserTask2"));
+
+        // Assert no user tasks are initially loaded
+        assertTrue(mRecentTasks.usersWithRecentsLoadedLocked().length == 0);
+
+        // Load user 0 tasks
+        mRecentTasks.loadUserRecentsLocked(TEST_USER_0_ID);
+        assertTrue(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(1, TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(2, TEST_USER_0_ID));
+
+        // Load user 1 tasks
+        mRecentTasks.loadUserRecentsLocked(TEST_USER_1_ID);
+        assertTrue(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_0_ID));
+        assertTrue(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_1_ID));
+        assertTrue(mRecentTasks.containsTaskId(1, TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(2, TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(1, TEST_USER_1_ID));
+        assertTrue(mRecentTasks.containsTaskId(2, TEST_USER_1_ID));
+
+        // Unload user 1 tasks
+        mRecentTasks.unloadUserDataFromMemoryLocked(TEST_USER_1_ID);
+        assertTrue(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_0_ID));
+        assertFalse(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_1_ID));
+        assertTrue(mRecentTasks.containsTaskId(1, TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(2, TEST_USER_0_ID));
+
+        // Unload user 0 tasks
+        mRecentTasks.unloadUserDataFromMemoryLocked(TEST_USER_0_ID);
+        assertFalse(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_0_ID));
+        assertFalse(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_1_ID));
+    }
+
+    @Test
+    public void testOrderedIteration() throws Exception {
+        MutableLong prevLastActiveTime = new MutableLong(0);
+        final ArrayList<TaskRecord> tasks = mRecentTasks.getRawTasks();
+        for (int i = 0; i < tasks.size(); i++) {
+            final TaskRecord task = tasks.get(i);
+            assertTrue(task.lastActiveTime >= prevLastActiveTime.value);
+            prevLastActiveTime.value = task.lastActiveTime;
+        }
+    }
+
+    @Test
+    public void testTrimToGlobalMaxNumRecents() throws Exception {
+        // Limit the global maximum number of recent tasks to a fixed size
+        mRecentTasks.setGlobalMaxNumTasks(2 /* globalMaxNumTasks */);
+
+        // Add N+1 tasks
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.add(mTasks.get(1));
+        mRecentTasks.add(mTasks.get(2));
+
+        // Ensure that the last task was trimmed as an inactive task
+        assertTrimmed(mTasks.get(0));
+    }
+
+    @Test
+    public void testTrimQuietProfileTasks() throws Exception {
+        TaskRecord qt1 = createTask(".QuietTask1", TEST_QUIET_USER_ID);
+        TaskRecord qt2 = createTask(".QuietTask2", TEST_QUIET_USER_ID);
+        mRecentTasks.add(qt1);
+        mRecentTasks.add(qt2);
+
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.add(mTasks.get(1));
+
+        // Ensure that the quiet user's tasks was trimmed once the new tasks were added
+        assertTrimmed(qt1, qt2);
+    }
+
+    @Test
+    public void testSessionDuration() throws Exception {
+        mRecentTasks.setParameters(-1 /* min */, -1 /* max */, 50 /* ms */);
+
+        TaskRecord t1 = createTask(".Task1");
+        t1.touchActiveTime();
+        mRecentTasks.add(t1);
+
+        // Force a small sleep just beyond the session duration
+        SystemClock.sleep(75);
+
+        TaskRecord t2 = createTask(".Task2");
+        t2.touchActiveTime();
+        mRecentTasks.add(t2);
+
+        // Assert that the old task has been removed due to being out of the active session
+        assertTrimmed(t1);
+    }
+
+    @Test
+    public void testVisibleTasks_excludedFromRecents() throws Exception {
+        mRecentTasks.setParameters(-1 /* min */, 4 /* max */, -1 /* ms */);
+
+        TaskRecord excludedTask1 = createTask(".ExcludedTask1", FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,
+                TEST_USER_0_ID);
+        TaskRecord excludedTask2 = createTask(".ExcludedTask2", FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,
+                TEST_USER_0_ID);
+
+        mRecentTasks.add(excludedTask1);
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.add(mTasks.get(1));
+        mRecentTasks.add(mTasks.get(2));
+        mRecentTasks.add(excludedTask2);
+
+        // The last excluded task should be trimmed, while the first-most excluded task should not
+        assertTrimmed(excludedTask1);
+    }
+
+    @Test
+    public void testVisibleTasks_minNum() throws Exception {
+        mRecentTasks.setParameters(5 /* min */, -1 /* max */, 25 /* ms */);
+
+        for (int i = 0; i < 4; i++) {
+            final TaskRecord task = mTasks.get(i);
+            task.touchActiveTime();
+            mRecentTasks.add(task);
+        }
+
+        // Force a small sleep just beyond the session duration
+        SystemClock.sleep(50);
+
+        // Add a new task to trigger tasks to be trimmed
+        mRecentTasks.add(mTasks.get(4));
+
+        // Ensure that there are a minimum number of tasks regardless of session length
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+    }
+
+    @Test
+    public void testVisibleTasks_maxNum() throws Exception {
+        mRecentTasks.setParameters(-1 /* min */, 3 /* max */, -1 /* ms */);
+
+        for (int i = 0; i < 5; i++) {
+            final TaskRecord task = mTasks.get(i);
+            task.touchActiveTime();
+            mRecentTasks.add(task);
+        }
+
+        // Ensure that only the last number of max tasks are kept
+        assertTrimmed(mTasks.get(0), mTasks.get(1));
+    }
+
+    private ComponentName createComponent(String className) {
+        return new ComponentName(mContext.getPackageName(), className);
+    }
+
+    private TaskRecord createTask(String className) {
+        return createTask(className, TEST_USER_0_ID);
+    }
+
+    private TaskRecord createTask(String className, int userId) {
+        return createTask(className, 0 /* flags */, userId);
+    }
+
+    private TaskRecord createTask(String className, int flags, int userId) {
+        TaskRecord task = createTask(mService.mStackSupervisor, createComponent(className), flags,
+                LAST_TASK_ID++, mStack);
+        task.userId = userId;
+        task.touchActiveTime();
+        return task;
+    }
+
+    private TaskRecord createDocumentTask(String className, String affinity) {
+        TaskRecord task = createTask(className, FLAG_ACTIVITY_NEW_DOCUMENT, TEST_USER_0_ID);
+        task.affinity = affinity;
+        return task;
+    }
+
+    private boolean arrayContainsUser(int[] userIds, int targetUserId) {
+        Arrays.sort(userIds);
+        return Arrays.binarySearch(userIds, targetUserId) >= 0;
+    }
+
+    private void assertTrimmed(TaskRecord... tasks) {
+        final ArrayList<TaskRecord> trimmed = mCallbacksRecorder.trimmed;
+        final ArrayList<TaskRecord> removed = mCallbacksRecorder.removed;
+        assertTrue("Expected " + tasks.length + " trimmed tasks, got " + trimmed.size(),
+                trimmed.size() == tasks.length);
+        assertTrue("Expected " + tasks.length + " removed tasks, got " + removed.size(),
+                removed.size() == tasks.length);
+        for (TaskRecord task : tasks) {
+            assertTrue("Expected trimmed task: " + task, trimmed.contains(task));
+            assertTrue("Expected removed task: " + task, removed.contains(task));
+        }
+    }
+
+    private static class CallbacksRecorder implements Callbacks {
+        ArrayList<TaskRecord> added = new ArrayList<>();
+        ArrayList<TaskRecord> trimmed = new ArrayList<>();
+        ArrayList<TaskRecord> removed = new ArrayList<>();
+
+        void clear() {
+            added.clear();
+            trimmed.clear();
+            removed.clear();
+        }
+
+        @Override
+        public void onRecentTaskAdded(TaskRecord task) {
+            added.add(task);
+        }
+
+        @Override
+        public void onRecentTaskRemoved(TaskRecord task, boolean wasTrimmed) {
+            if (wasTrimmed) {
+                trimmed.add(task);
+            }
+            removed.add(task);
+        }
+    }
+
+    private static class TestTaskPersister extends TaskPersister {
+
+        SparseBooleanArray userTaskIdsOverride;
+        ArrayList<TaskRecord> userTasksOverride;
+
+        TestTaskPersister(File workingDir) {
+            super(workingDir);
+        }
+
+        @Override
+        SparseBooleanArray loadPersistedTaskIdsForUser(int userId) {
+            if (userTaskIdsOverride != null) {
+                return userTaskIdsOverride;
+            }
+            return super.loadPersistedTaskIdsForUser(userId);
+        }
+
+        @Override
+        List<TaskRecord> restoreTasksForUserLocked(int userId, SparseBooleanArray preaddedTasks) {
+            if (userTasksOverride != null) {
+                return userTasksOverride;
+            }
+            return super.restoreTasksForUserLocked(userId, preaddedTasks);
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java
index f4c4ea9..1bb93cc 100644
--- a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java
@@ -247,6 +247,26 @@
         assertEquals(7, updates.size());
     }
 
+    public void testUpdatesReceived_queueEmptyAfterStartListening() {
+        int widgetId = setupHostAndWidget();
+        int widgetId2 = bindNewWidget();
+        mService.stopListening(mPkgName, HOST_ID);
+
+        sendDummyUpdates(widgetId, 22, 23);
+        sendDummyUpdates(widgetId2, 100, 101, 102);
+
+        List<PendingHostUpdate> updates = mService.startListening(
+                mMockHost, mPkgName, HOST_ID, new int[]{widgetId, widgetId2}).getList();
+        // 3 updates for first widget and 4 for second
+        assertEquals(7, updates.size());
+
+        // Stop and start listening again
+        mService.stopListening(mPkgName, HOST_ID);
+        updates = mService.startListening(
+                mMockHost, mPkgName, HOST_ID, new int[]{widgetId, widgetId2}).getList();
+        assertTrue(updates.isEmpty());
+    }
+
     public void testGetInstalledProvidersForPackage() {
         List<AppWidgetProviderInfo> allProviders = mManager.getInstalledProviders();
         assertTrue(!allProviders.isEmpty());
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 3c64582..6bb5bc6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -319,7 +319,8 @@
         }
 
         @Override
-        boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) {
+        boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId,
+                int callingPid, int callingUid) {
             return mDefaultLauncherChecker.test(callingPackage, userId);
         }
 
@@ -452,6 +453,11 @@
         }
 
         @Override
+        boolean injectCheckAccessShortcutsPermission(int callingPid, int callingUid) {
+            return mInjectCheckAccessShortcutsPermission;
+        }
+
+        @Override
         void wtf(String message, Throwable th) {
             // During tests, WTF is fatal.
             fail(message + "  exception: " + th + "\n" + Log.getStackTraceString(th));
@@ -697,6 +703,8 @@
 
     protected String mInjectedBuildFingerprint = "build1";
 
+    protected boolean mInjectCheckAccessShortcutsPermission = false;
+
     static {
         QUERY_ALL.setQueryFlags(
                 ShortcutQuery.FLAG_GET_ALL_KINDS);
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 951f226..b5e8e1c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -15,6 +15,11 @@
  */
 package com.android.server.pm;
 
+import static android.content.pm.ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED;
+import static android.content.pm.ShortcutInfo.DISABLED_REASON_NOT_DISABLED;
+import static android.content.pm.ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH;
+import static android.content.pm.ShortcutInfo.DISABLED_REASON_VERSION_LOWER;
+
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyOrNull;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyStringOrNull;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDisabled;
@@ -71,7 +76,9 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.PinItemRequest;
 import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.PackageInfo;
 import android.content.pm.ShortcutInfo;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
@@ -101,7 +108,6 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.function.BiConsumer;
-import java.util.function.BiPredicate;
 
 /**
  * Tests for ShortcutService and ShortcutManager.
@@ -250,7 +256,7 @@
         final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                 getTestContext().getResources(), R.drawable.icon2));
         final Icon icon3 = Icon.createWithAdaptiveBitmap(BitmapFactory.decodeResource(
-            getTestContext().getResources(), R.drawable.icon2));
+                getTestContext().getResources(), R.drawable.icon2));
 
         final ShortcutInfo si1 = makeShortcut(
                 "shortcut1",
@@ -706,13 +712,13 @@
         assertBitmapSize(128, 128, bmp);
 
         Drawable dr = mLauncherApps.getShortcutIconDrawable(
-            makeShortcutWithIcon("bmp64x64", bmp64x64_maskable), 0);
+                makeShortcutWithIcon("bmp64x64", bmp64x64_maskable), 0);
         assertTrue(dr instanceof AdaptiveIconDrawable);
         float viewportPercentage = 1 / (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction());
         assertEquals((int) (bmp64x64_maskable.getBitmap().getWidth() * viewportPercentage),
-            dr.getIntrinsicWidth());
+                dr.getIntrinsicWidth());
         assertEquals((int) (bmp64x64_maskable.getBitmap().getHeight() * viewportPercentage),
-            dr.getIntrinsicHeight());
+                dr.getIntrinsicHeight());
     }
 
     public void testCleanupDanglingBitmaps() throws Exception {
@@ -1118,8 +1124,8 @@
             // Set resource icon
             assertTrue(mManager.updateShortcuts(list(
                     new ShortcutInfo.Builder(mClientContext, "s1")
-                    .setIcon(Icon.createWithResource(getTestContext(), R.drawable.black_32x32))
-                    .build()
+                            .setIcon(Icon.createWithResource(getTestContext(), R.drawable.black_32x32))
+                            .build()
             )));
 
             assertWith(getCallerShortcuts())
@@ -1131,9 +1137,9 @@
             // Set bitmap icon
             assertTrue(mManager.updateShortcuts(list(
                     new ShortcutInfo.Builder(mClientContext, "s1")
-                    .setIcon(Icon.createWithBitmap(BitmapFactory.decodeResource(
-                            getTestContext().getResources(), R.drawable.black_64x64)))
-                    .build()
+                            .setIcon(Icon.createWithBitmap(BitmapFactory.decodeResource(
+                                    getTestContext().getResources(), R.drawable.black_64x64)))
+                            .build()
             )));
 
             assertWith(getCallerShortcuts())
@@ -1669,6 +1675,10 @@
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
 
+            mManager.updateShortcuts(list(
+                    new ShortcutInfo.Builder(mClientContext, "s2").setDisabledMessage("xyz")
+                            .build()));
+
             mManager.disableShortcuts(list("s2"));
 
             assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
@@ -1704,6 +1714,10 @@
             assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))
                     .haveIds("s2")
+                    .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BY_APP)
+                    .forAllShortcuts(si -> {
+                        assertEquals("xyz", si.getDisabledMessage());
+                    })
                     .areAllPinned()
                     .areAllNotWithKeyFieldsOnly()
                     .areAllDisabled();
@@ -1888,7 +1902,7 @@
                     "s1", "s2");
         });
 
-        dumpsysOnLogcat();
+        dumpsysOnLogcat("Before launcher 2");
 
         runWithCaller(LAUNCHER_2, USER_0, () -> {
             // Launcher2 still has no pinned ones.
@@ -1901,6 +1915,27 @@
                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser())))
                     /* none */);
 
+            // Make sure FLAG_MATCH_ALL_PINNED will be ignored.
+            assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+                    /* activity =*/ null, ShortcutQuery.FLAG_MATCH_PINNED
+                            | ShortcutQuery.FLAG_MATCH_ALL_PINNED), getCallingUser()))
+                    .isEmpty();
+
+            // Make sure the special permission works.
+            mInjectCheckAccessShortcutsPermission = true;
+
+            dumpsysOnLogcat("All-pinned");
+
+            assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+                    /* activity =*/ null, ShortcutQuery.FLAG_MATCH_PINNED
+                            | ShortcutQuery.FLAG_MATCH_ALL_PINNED), getCallingUser()))
+                    .haveIds("s1", "s2");
+            assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+                    /* activity =*/ null, ShortcutQuery.FLAG_MATCH_PINNED), getCallingUser()))
+                    .isEmpty();
+
+            mInjectCheckAccessShortcutsPermission = false;
+
             assertShortcutIds(assertAllDynamic(
                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
@@ -2126,7 +2161,7 @@
 
             final ShortcutQuery q = new ShortcutQuery().setQueryFlags(
                     ShortcutQuery.FLAG_MATCH_DYNAMIC | ShortcutQuery.FLAG_MATCH_PINNED
-                    | ShortcutQuery.FLAG_MATCH_MANIFEST);
+                            | ShortcutQuery.FLAG_MATCH_MANIFEST);
 
             // No shortcuts are visible.
             assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_0)).isEmpty();
@@ -2668,10 +2703,10 @@
                     "Title 1",
                     makeComponent(ShortcutActivity.class),
                     /* icon =*/ null,
-                    new Intent[] {makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
+                    new Intent[]{makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
                             "key1", "val1", "nest", makeBundle("key", 123))
                             .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK),
-                    new Intent("act2").setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)},
+                            new Intent("act2").setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)},
                     /* rank */ 10);
 
             final ShortcutInfo s1_2 = makeShortcut(
@@ -2776,8 +2811,8 @@
             // Not launchable.
             doReturn(ActivityManager.START_CLASS_NOT_FOUND)
                     .when(mMockActivityManagerInternal).startActivitiesAsPackage(
-                            anyStringOrNull(), anyInt(),
-                            anyOrNull(Intent[].class), anyOrNull(Bundle.class));
+                    anyStringOrNull(), anyInt(),
+                    anyOrNull(Intent[].class), anyOrNull(Bundle.class));
             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
                     ActivityNotFoundException.class);
 
@@ -2911,7 +2946,7 @@
                     .revertToOriginalList()
                     .selectByIds("s1", "s2")
                     .areAllDynamic()
-                    ;
+            ;
         });
 
         // 3 Update the app with no manifest shortcuts.  (Pinned one will survive.)
@@ -3309,13 +3344,13 @@
         });
 
 
-        final SparseArray<ShortcutUser> users =  mService.getShortcutsForTest();
+        final SparseArray<ShortcutUser> users = mService.getShortcutsForTest();
         assertEquals(2, users.size());
         assertEquals(USER_0, users.keyAt(0));
         assertEquals(USER_10, users.keyAt(1));
 
-        final ShortcutUser user0 =  users.get(USER_0);
-        final ShortcutUser user10 =  users.get(USER_10);
+        final ShortcutUser user0 = users.get(USER_0);
+        final ShortcutUser user10 = users.get(USER_10);
 
 
         // Check the registered packages.
@@ -3531,7 +3566,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -3548,7 +3583,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -3853,52 +3888,77 @@
         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
     }
 
-    protected void checkCanRestoreTo(boolean expected, ShortcutPackageInfo spi,
-            int version, String... signatures) {
-        assertEquals(expected, spi.canRestoreTo(mService, genPackage(
-                "dummy", /* uid */ 0, version, signatures)));
+    protected void checkCanRestoreTo(int expected, ShortcutPackageInfo spi,
+            boolean anyVersionOk, int version, boolean nowBackupAllowed, String... signatures) {
+        final PackageInfo pi = genPackage("dummy", /* uid */ 0, version, signatures);
+        if (!nowBackupAllowed) {
+            pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP;
+        }
+        assertEquals(expected, spi.canRestoreTo(mService, pi, anyVersionOk));
     }
 
     public void testCanRestoreTo() {
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
-        addPackage(CALLING_PACKAGE_2, CALLING_UID_1, 10, "sig1", "sig2");
+        addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 10, "sig1", "sig2");
+        addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 10, "sig1");
+
+        updatePackageInfo(CALLING_PACKAGE_3,
+                pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
 
         final ShortcutPackageInfo spi1 = ShortcutPackageInfo.generateForInstalledPackageForTest(
                 mService, CALLING_PACKAGE_1, USER_0);
         final ShortcutPackageInfo spi2 = ShortcutPackageInfo.generateForInstalledPackageForTest(
                 mService, CALLING_PACKAGE_2, USER_0);
+        final ShortcutPackageInfo spi3 = ShortcutPackageInfo.generateForInstalledPackageForTest(
+                mService, CALLING_PACKAGE_3, USER_0);
 
-        checkCanRestoreTo(true, spi1, 10, "sig1");
-        checkCanRestoreTo(true, spi1, 10, "x", "sig1");
-        checkCanRestoreTo(true, spi1, 10, "sig1", "y");
-        checkCanRestoreTo(true, spi1, 10, "x", "sig1", "y");
-        checkCanRestoreTo(true, spi1, 11, "sig1");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "sig1");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "x", "sig1");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "sig1", "y");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "x", "sig1", "y");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 11, true, "sig1");
 
-        checkCanRestoreTo(false, spi1, 10 /* empty */);
-        checkCanRestoreTo(false, spi1, 10, "x");
-        checkCanRestoreTo(false, spi1, 10, "x", "y");
-        checkCanRestoreTo(false, spi1, 10, "x");
-        checkCanRestoreTo(false, spi1, 9, "sig1");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true/* empty */);
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true, "x");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true, "x", "y");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true, "x");
+        checkCanRestoreTo(DISABLED_REASON_VERSION_LOWER, spi1, false, 9, true, "sig1");
 
-        checkCanRestoreTo(true, spi2, 10, "sig1", "sig2");
-        checkCanRestoreTo(true, spi2, 10, "sig2", "sig1");
-        checkCanRestoreTo(true, spi2, 10, "x", "sig1", "sig2");
-        checkCanRestoreTo(true, spi2, 10, "x", "sig2", "sig1");
-        checkCanRestoreTo(true, spi2, 10, "sig1", "sig2", "y");
-        checkCanRestoreTo(true, spi2, 10, "sig2", "sig1", "y");
-        checkCanRestoreTo(true, spi2, 10, "x", "sig1", "sig2", "y");
-        checkCanRestoreTo(true, spi2, 10, "x", "sig2", "sig1", "y");
-        checkCanRestoreTo(true, spi2, 11, "x", "sig2", "sig1", "y");
+        // Any version okay.
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, true, 9, true, "sig1");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, true, 9, true, "sig1");
 
-        checkCanRestoreTo(false, spi2, 10, "sig1", "sig2x");
-        checkCanRestoreTo(false, spi2, 10, "sig2", "sig1x");
-        checkCanRestoreTo(false, spi2, 10, "x", "sig1x", "sig2");
-        checkCanRestoreTo(false, spi2, 10, "x", "sig2x", "sig1");
-        checkCanRestoreTo(false, spi2, 10, "sig1", "sig2x", "y");
-        checkCanRestoreTo(false, spi2, 10, "sig2", "sig1x", "y");
-        checkCanRestoreTo(false, spi2, 10, "x", "sig1x", "sig2", "y");
-        checkCanRestoreTo(false, spi2, 10, "x", "sig2x", "sig1", "y");
-        checkCanRestoreTo(false, spi2, 11, "x", "sig2x", "sig1", "y");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig1", "sig2");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig2", "sig1");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig1", "sig2");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig2", "sig1");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig1", "sig2", "y");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig2", "sig1", "y");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig1", "sig2", "y");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig2", "sig1", "y");
+        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 11, true, "x", "sig2", "sig1", "y");
+
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
+                spi2, false, 10, true, "sig1", "sig2x");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
+                spi2, false, 10, true, "sig2", "sig1x");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
+                spi2, false, 10, true, "x", "sig1x", "sig2");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
+                spi2, false, 10, true, "x", "sig2x", "sig1");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
+                spi2, false, 10, true, "sig1", "sig2x", "y");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
+                spi2, false, 10, true, "sig2", "sig1x", "y");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
+                spi2, false, 10, true, "x", "sig1x", "sig2", "y");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
+                spi2, false, 10, true, "x", "sig2x", "sig1", "y");
+        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
+                spi2, false, 11, true, "x", "sig2x", "sig1", "y");
+
+        checkCanRestoreTo(DISABLED_REASON_BACKUP_NOT_SUPPORTED, spi1, true, 10, false, "sig1");
+        checkCanRestoreTo(DISABLED_REASON_BACKUP_NOT_SUPPORTED, spi3, true, 10, true, "sig1");
     }
 
     public void testHandlePackageDelete() {
@@ -3929,7 +3989,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertWith(getCallerShortcuts())
@@ -4080,7 +4140,7 @@
         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
 
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageDataClear(CALLING_PACKAGE_1, USER_0));
 
         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
@@ -4099,7 +4159,7 @@
 
         mRunningUsers.put(USER_10, true);
 
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageDataClear(CALLING_PACKAGE_2, USER_10));
 
         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
@@ -4126,7 +4186,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4389,7 +4449,7 @@
 
         // Update the package.
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -4524,7 +4584,7 @@
         mRunningUsers.put(USER_10, true);
 
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4552,11 +4612,11 @@
                     .revertToOriginalList()
                     .selectByIds("ms1-alt", "s2")
                     .areAllWithActivity(ACTIVITY2)
-                    ;
+            ;
         });
 
         // First, no changes.
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4579,7 +4639,7 @@
 
         // Disable activity 1
         mEnabledActivityChecker = (activity, userId) -> !ACTIVITY1.equals(activity);
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4599,7 +4659,7 @@
         // Re-enable activity 1.
         // Manifest shortcuts will be re-published, but dynamic ones are not.
         mEnabledActivityChecker = (activity, userId) -> true;
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4617,13 +4677,13 @@
                     .revertToOriginalList()
                     .selectByIds("ms1-alt", "s2")
                     .areAllWithActivity(ACTIVITY2)
-                    ;
+            ;
         });
 
         // Disable activity 2
         // Because "ms1-alt" and "s2" are both pinned, they will remain, but disabled.
         mEnabledActivityChecker = (activity, userId) -> !ACTIVITY2.equals(activity);
-                mService.mPackageMonitor.onReceive(getTestContext(),
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4686,7 +4746,7 @@
         setCaller(LAUNCHER_1, USER_0);
         assertForLauncherCallback(mLauncherApps, () -> {
             updatePackageVersion(CALLING_PACKAGE_1, 1);
-                    mService.mPackageMonitor.onReceive(getTestContext(),
+            mService.mPackageMonitor.onReceive(getTestContext(),
                     genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
                 // Make sure the launcher gets callbacks.
@@ -4708,12 +4768,11 @@
                     .areAllNotDynamic()
                     .areAllDisabled()
                     .areAllPinned()
-                    ;
+            ;
         });
     }
 
     protected void prepareForBackupTest() {
-
         prepareCrossProfileDataSet();
 
         backupAndRestore();
@@ -4749,66 +4808,45 @@
         assertFileExistsWithContent("user-0/shortcut_dump/restore-4.txt");
         assertFileExistsWithContent("user-0/shortcut_dump/restore-5-finish.txt");
 
-        checkBackupAndRestore_success();
+        checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
     public void testBackupAndRestore_backupRestoreTwice() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        dumpsysOnLogcat("Before second backup");
+        checkBackupAndRestore_success(/*firstRestore=*/ true);
+
+        // Run a backup&restore again. Note the shortcuts that weren't restored in the previous
+        // restore are disabled, so they won't be restored again.
+        dumpsysOnLogcat("Before second backup&restore");
 
         backupAndRestore();
 
-        dumpsysOnLogcat("After second backup");
+        dumpsysOnLogcat("After second backup&restore");
 
-        checkBackupAndRestore_success();
-    }
-
-    public void testBackupAndRestore_backupRestoreMultiple() {
-        prepareForBackupTest();
-
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
-        // This also shouldn't affect the result.
-        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
-            assertTrue(mManager.setDynamicShortcuts(list(
-                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
-                    makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
-        });
-
-        backupAndRestore();
-
-        checkBackupAndRestore_success();
+        checkBackupAndRestore_success(/*firstRestore=*/ false);
     }
 
     public void testBackupAndRestore_restoreToNewVersion() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 2);
         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 5);
 
-        checkBackupAndRestore_success();
+        checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
     public void testBackupAndRestore_restoreToSuperSetSignatures() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
         // Change package signatures.
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 1, "sigx", CALLING_PACKAGE_1);
         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 4, LAUNCHER_1, "sigy");
 
-        checkBackupAndRestore_success();
+        checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
-    protected void checkBackupAndRestore_success() {
+    protected void checkBackupAndRestore_success(boolean firstRestore) {
         // Make sure non-system user is not restored.
         final ShortcutUser userP0 = mService.getUserShortcutsLocked(USER_P0);
         assertEquals(0, userP0.getAllPackagesForTest().size());
@@ -4818,12 +4856,13 @@
         final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_0);
         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_1));
         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_2));
+
+        assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
         assertExistsAndShadow(user0.getAllLaunchersForTest().get(
                 PackageWithUser.of(USER_0, LAUNCHER_1)));
         assertExistsAndShadow(user0.getAllLaunchersForTest().get(
                 PackageWithUser.of(USER_0, LAUNCHER_2)));
 
-        assertNull(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
         assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_0, LAUNCHER_3)));
         assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_P0, LAUNCHER_1)));
 
@@ -4835,14 +4874,16 @@
 
                     .revertToOriginalList()
                     .selectPinned()
-                    .haveIds("s1", "s2");
+                    .haveIds("s1", "s2")
+                    .areAllEnabled();
         });
 
         installPackage(USER_0, LAUNCHER_1);
         runWithCaller(LAUNCHER_1, USER_0, () -> {
             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
                     .areAllPinned()
-                    .haveIds("s1");
+                    .haveIds("s1")
+                    .areAllEnabled();
 
             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
                     .isEmpty();
@@ -4862,17 +4903,20 @@
 
                     .revertToOriginalList()
                     .selectPinned()
-                    .haveIds("s1", "s2", "s3");
+                    .haveIds("s1", "s2", "s3")
+                    .areAllEnabled();
         });
 
         runWithCaller(LAUNCHER_1, USER_0, () -> {
             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
                     .areAllPinned()
-                    .haveIds("s1");
+                    .haveIds("s1")
+                    .areAllEnabled();
 
             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
                     .areAllPinned()
-                    .haveIds("s1", "s2");
+                    .haveIds("s1", "s2")
+                    .areAllEnabled();
 
             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
                     .isEmpty();
@@ -4910,14 +4954,28 @@
         runWithCaller(LAUNCHER_2, USER_0, () -> {
             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
                     .areAllPinned()
-                    .haveIds("s2");
+                    .haveIds("s2")
+                    .areAllEnabled();
 
             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
                     .areAllPinned()
-                    .haveIds("s2", "s3");
+                    .haveIds("s2", "s3")
+                    .areAllEnabled();
 
-            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
-                    .isEmpty();
+            if (firstRestore) {
+                assertWith(
+                        mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+                        .haveIds("s2", "s3", "s4")
+                        .areAllDisabled()
+                        .areAllPinned()
+                        .areAllNotDynamic()
+                        .areAllWithDisabledReason(
+                                ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
+            } else {
+                assertWith(
+                        mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+                        .isEmpty();
+            }
 
             assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
                     .isEmpty();
@@ -4937,14 +4995,27 @@
         runWithCaller(LAUNCHER_1, USER_0, () -> {
             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
                     .areAllPinned()
-                    .haveIds("s1");
+                    .haveIds("s1")
+                    .areAllEnabled();
 
             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
                     .areAllPinned()
-                    .haveIds("s1", "s2");
+                    .haveIds("s1", "s2")
+                    .areAllEnabled();
 
-            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
-                    .isEmpty();
+            if (firstRestore) {
+                assertWith(
+                        mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+                        .haveIds("s1", "s2", "s3")
+                        .areAllDisabled()
+                        .areAllPinned()
+                        .areAllNotDynamic()
+                        .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
+            } else {
+                assertWith(
+                        mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+                        .isEmpty();
+            }
 
             assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
                     .isEmpty();
@@ -4954,45 +5025,39 @@
         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
             assertWith(getCallerVisibleShortcuts())
                     .areAllPinned()
-                    .haveIds("s1", "s2", "s3");
+                    .haveIds("s1", "s2", "s3")
+                    .areAllEnabled();
         });
     }
 
     public void testBackupAndRestore_publisherLowerVersion() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 0); // Lower version
 
-        checkBackupAndRestore_publisherNotRestored();
+        checkBackupAndRestore_publisherNotRestored(ShortcutInfo.DISABLED_REASON_VERSION_LOWER);
     }
 
     public void testBackupAndRestore_publisherWrongSignature() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sigx"); // different signature
 
-        checkBackupAndRestore_publisherNotRestored();
+        checkBackupAndRestore_publisherNotRestored(ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH);
     }
 
     public void testBackupAndRestore_publisherNoLongerBackupTarget() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
         updatePackageInfo(CALLING_PACKAGE_1,
                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
 
-        checkBackupAndRestore_publisherNotRestored();
+        checkBackupAndRestore_publisherNotRestored(
+                ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
     }
 
-    protected void checkBackupAndRestore_publisherNotRestored() {
+    protected void checkBackupAndRestore_publisherNotRestored(
+            int package1DisabledReason) {
         installPackage(USER_0, CALLING_PACKAGE_1);
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertEquals(0, mManager.getDynamicShortcuts().size());
@@ -5014,27 +5079,53 @@
 
         installPackage(USER_0, LAUNCHER_1);
         runWithCaller(LAUNCHER_1, USER_0, () -> {
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
-                    /* empty */);
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
-                    "s1", "s2");
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
-                    /* empty */);
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+                    .haveIds("s1")
+                    .areAllPinned()
+                    .areAllDisabled()
+                    .areAllWithDisabledReason(package1DisabledReason)
+                    .forAllShortcuts(si -> {
+                        switch (package1DisabledReason) {
+                            case ShortcutInfo.DISABLED_REASON_VERSION_LOWER:
+                                assertEquals("This shortcut requires latest app",
+                                        si.getDisabledMessage());
+                                break;
+                            case ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH:
+                                assertEquals(
+                                        "Couldn\u2019t restore shortcut because of app"
+                                        + " signature mismatch",
+                                        si.getDisabledMessage());
+                                break;
+                            case ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED:
+                                assertEquals(
+                                        "Couldn\u2019t restore shortcut because app"
+                                        + " doesn\u2019t support backup and restore",
+                                        si.getDisabledMessage());
+                                break;
+                            default:
+                                fail("Unhandled disabled reason: " + package1DisabledReason);
+                        }
+                    });
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+                    .haveIds("s1", "s2")
+                    .areAllPinned()
+                    .areAllEnabled();
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+                    .isEmpty();
         });
         installPackage(USER_0, LAUNCHER_2);
         runWithCaller(LAUNCHER_2, USER_0, () -> {
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
-                    /* empty */);
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
-                    "s2", "s3");
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
-                    /* empty */);
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+                    .haveIds("s2")
+                    .areAllPinned()
+                    .areAllDisabled()
+                    .areAllWithDisabledReason(package1DisabledReason);
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+                    .haveIds("s2", "s3")
+                    .areAllPinned()
+                    .areAllEnabled();
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+                    .isEmpty();
         });
 
         installPackage(USER_0, CALLING_PACKAGE_3);
@@ -5044,46 +5135,51 @@
         });
 
         runWithCaller(LAUNCHER_1, USER_0, () -> {
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
-                    /* empty */);
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
-                    "s1", "s2");
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
-                    /* empty */);
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+                    .haveIds("s1")
+                    .areAllPinned()
+                    .areAllDisabled()
+                    .areAllWithDisabledReason(package1DisabledReason);
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+                    .haveIds("s1", "s2")
+                    .areAllPinned()
+                    .areAllEnabled();
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+                    .haveIds("s1", "s2", "s3")
+                    .areAllPinned()
+                    .areAllDisabled()
+                    .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
         });
         runWithCaller(LAUNCHER_2, USER_0, () -> {
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
-                    /* empty */);
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
-                    "s2", "s3");
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
-                    /* empty */);
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+                    .haveIds("s2")
+                    .areAllPinned()
+                    .areAllDisabled()
+                    .areAllWithDisabledReason(package1DisabledReason);
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+                    .haveIds("s2", "s3")
+                    .areAllPinned()
+                    .areAllEnabled();
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+                    .haveIds("s2", "s3", "s4")
+                    .areAllPinned()
+                    .areAllDisabled()
+                    .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
         });
     }
 
     public void testBackupAndRestore_launcherLowerVersion() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 0); // Lower version
 
-        checkBackupAndRestore_launcherNotRestored();
+        // Note, we restore pinned shortcuts even if the launcher is of a lower version.
+        checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
     public void testBackupAndRestore_launcherWrongSignature() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 10, "sigx"); // different signature
 
         checkBackupAndRestore_launcherNotRestored();
@@ -5092,9 +5188,6 @@
     public void testBackupAndRestore_launcherNoLongerBackupTarget() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
         updatePackageInfo(LAUNCHER_1,
                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
 
@@ -5185,18 +5278,12 @@
             assertShortcutIds(assertAllPinned(
                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
                     "s2", "s3");
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
-                    /* empty */);
         });
     }
 
     public void testBackupAndRestore_launcherAndPackageNoLongerBackupTarget() {
         prepareForBackupTest();
 
-        // Note doing a backup & restore again here shouldn't affect the result.
-        backupAndRestore();
-
         updatePackageInfo(CALLING_PACKAGE_1,
                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
 
@@ -5235,15 +5322,15 @@
         });
         installPackage(USER_0, LAUNCHER_2);
         runWithCaller(LAUNCHER_2, USER_0, () -> {
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
-                    /* empty */);
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
-                    "s2", "s3");
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
-                    /* empty */);
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+                    .areAllPinned()
+                    .haveIds("s2")
+                    .areAllDisabled();
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+                    .areAllPinned()
+                    .haveIds("s2", "s3");
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+                    .isEmpty();
         });
 
         // Because launcher 1 wasn't restored, "s1" is no longer pinned.
@@ -5272,15 +5359,21 @@
                     /* empty */);
         });
         runWithCaller(LAUNCHER_2, USER_0, () -> {
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
-                    /* empty */);
-            assertShortcutIds(assertAllPinned(
-                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
-                    "s2", "s3");
-            assertShortcutIds(assertAllPinned(
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+                    .areAllPinned()
+                    .haveIds("s2")
+                    .areAllDisabled();
+            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+                    .areAllPinned()
+                    .haveIds("s2", "s3");
+            assertWith(
                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
-                    /* empty */);
+                    .haveIds("s2", "s3", "s4")
+                    .areAllDisabled()
+                    .areAllPinned()
+                    .areAllNotDynamic()
+                    .areAllWithDisabledReason(
+                            ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
         });
     }
 
@@ -5305,12 +5398,12 @@
         final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_0);
         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_1));
         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_2));
+        assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
         assertExistsAndShadow(user0.getAllLaunchersForTest().get(
                 PackageWithUser.of(USER_0, LAUNCHER_1)));
         assertExistsAndShadow(user0.getAllLaunchersForTest().get(
                 PackageWithUser.of(USER_0, LAUNCHER_2)));
 
-        assertNull(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
         assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_0, LAUNCHER_3)));
         assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_P0, LAUNCHER_1)));
 
@@ -5421,7 +5514,7 @@
                     .revertToOriginalList()
                     .selectByIds("s1", "s2")
                     .areAllNotDynamic()
-                    ;
+            ;
         });
     }
 
@@ -5555,6 +5648,287 @@
         });
     }
 
+
+    /**
+     * Restored to a lower version with no manifest shortcuts. All shortcuts are now invisible,
+     * and all calls from the publisher should ignore them.
+     */
+    public void testBackupAndRestore_disabledShortcutsAreIgnored() {
+        // Publish two manifest shortcuts.
+        addManifestShortcutResource(
+                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+                R.xml.shortcut_5_altalt);
+        updatePackageVersion(CALLING_PACKAGE_1, 1);
+        mService.mPackageMonitor.onReceive(mServiceContext,
+                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertTrue(mManager.setDynamicShortcuts(list(
+                    makeShortcutWithShortLabel("s1", "original-title"),
+                    makeShortcut("s2"), makeShortcut("s3"))));
+        });
+
+        // Pin from launcher 1.
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+                    list("ms1", "ms2", "ms3", "ms4", "s1", "s2"), HANDLE_USER_0);
+        });
+
+        backupAndRestore();
+
+        // Lower the version and remove the manifest shortcuts.
+        addManifestShortcutResource(
+                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+                R.xml.shortcut_0);
+        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 0); // Lower version
+
+        // When re-installing the app, the manifest shortcut should be re-published.
+        mService.mPackageMonitor.onReceive(mServiceContext,
+                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+        mService.mPackageMonitor.onReceive(mServiceContext,
+                genPackageAddIntent(LAUNCHER_1, USER_0));
+
+        // No shortcuts should be visible to the publisher.
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertWith(getCallerVisibleShortcuts())
+                    .isEmpty();
+        });
+
+        final Runnable checkAllDisabledForLauncher = () -> {
+            runWithCaller(LAUNCHER_1, USER_0, () -> {
+                assertWith(getShortcutAsLauncher(USER_0))
+                        .areAllPinned()
+                        .haveIds("ms1", "ms2", "ms3", "ms4", "s1", "s2")
+                        .areAllDisabled()
+                        .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_VERSION_LOWER)
+
+                        .forShortcutWithId("s1", si -> {
+                            assertEquals("original-title", si.getShortLabel());
+                        })
+                        .forShortcutWithId("ms1", si -> {
+                            assertEquals("string-com.android.test.1-user:0-res:"
+                                            + R.string.shortcut_title1 + "/en"
+                                    , si.getShortLabel());
+                        })
+                        .forShortcutWithId("ms2", si -> {
+                            assertEquals("string-com.android.test.1-user:0-res:"
+                                            + R.string.shortcut_title2 + "/en"
+                                    , si.getShortLabel());
+                        })
+                        .forShortcutWithId("ms3", si -> {
+                            assertEquals("string-com.android.test.1-user:0-res:"
+                                            + R.string.shortcut_title1 + "/en"
+                                    , si.getShortLabel());
+                            assertEquals("string-com.android.test.1-user:0-res:"
+                                            + R.string.shortcut_title2 + "/en"
+                                    , si.getLongLabel());
+                        })
+                        .forShortcutWithId("ms4", si -> {
+                            assertEquals("string-com.android.test.1-user:0-res:"
+                                            + R.string.shortcut_title2 + "/en"
+                                    , si.getShortLabel());
+                            assertEquals("string-com.android.test.1-user:0-res:"
+                                            + R.string.shortcut_title2 + "/en"
+                                    , si.getLongLabel());
+                        });
+            });
+        };
+
+        checkAllDisabledForLauncher.run();
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+
+            makeCallerForeground(); // CALLING_PACKAGE_1 is now in the foreground.
+
+            // All changing API calls should be ignored.
+
+            getManager().enableShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
+            checkAllDisabledForLauncher.run();
+
+            getManager().enableShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
+            checkAllDisabledForLauncher.run();
+
+            getManager().enableShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
+            checkAllDisabledForLauncher.run();
+
+            getManager().removeAllDynamicShortcuts();
+            getManager().removeDynamicShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
+            checkAllDisabledForLauncher.run();
+
+            getManager().updateShortcuts(list(makeShortcutWithShortLabel("s1", "new-title")));
+            checkAllDisabledForLauncher.run();
+
+
+            // Add a shortcut -- even though ms1 was immutable, it will succeed.
+            assertTrue(getManager().addDynamicShortcuts(list(
+                    makeShortcutWithShortLabel("ms1", "original-title"))));
+
+            runWithCaller(LAUNCHER_1, USER_0, () -> {
+                assertWith(getShortcutAsLauncher(USER_0))
+                        .haveIds("ms1", "ms2", "ms3", "ms4", "s1", "s2")
+
+                        .selectByIds("ms1")
+                        .areAllEnabled()
+                        .areAllDynamic()
+                        .areAllPinned()
+                        .forAllShortcuts(si -> {
+                            assertEquals("original-title", si.getShortLabel());
+                        })
+
+                        // The rest still exist and disabled.
+                        .revertToOriginalList()
+                        .selectByIds("ms2", "ms3", "ms4", "s1", "s2")
+                        .areAllDisabled()
+                        .areAllPinned()
+                ;
+            });
+
+            assertTrue(getManager().setDynamicShortcuts(list(
+                    makeShortcutWithShortLabel("ms2", "new-title-2"))));
+
+            runWithCaller(LAUNCHER_1, USER_0, () -> {
+                assertWith(getShortcutAsLauncher(USER_0))
+                        .haveIds("ms1", "ms2", "ms3", "ms4", "s1", "s2")
+
+                        .selectByIds("ms1")
+                        .areAllEnabled()
+                        .areAllNotDynamic() // ms1 was not in the list, so no longer dynamic.
+                        .areAllPinned()
+                        .areAllMutable()
+                        .forAllShortcuts(si -> {
+                            assertEquals("original-title", si.getShortLabel());
+                        })
+
+                        .revertToOriginalList()
+                        .selectByIds("ms2")
+                        .areAllEnabled()
+                        .areAllDynamic()
+                        .areAllPinned()
+                        .areAllMutable()
+                        .forAllShortcuts(si -> {
+                            assertEquals("new-title-2", si.getShortLabel());
+                        })
+
+                        // The rest still exist and disabled.
+                        .revertToOriginalList()
+                        .selectByIds("ms3", "ms4", "s1", "s2")
+                        .areAllDisabled()
+                        .areAllPinned()
+                ;
+            });
+
+            // Prepare for requestPinShortcut().
+            setDefaultLauncher(USER_0, mMainActivityFetcher.apply(LAUNCHER_1, USER_0));
+            mPinConfirmActivityFetcher = (packageName, userId) ->
+                    new ComponentName(packageName, PIN_CONFIRM_ACTIVITY_CLASS);
+
+            mManager.requestPinShortcut(
+                    makeShortcutWithShortLabel("ms3", "new-title-3"),
+                    /*PendingIntent=*/ null);
+
+            // Note this was pinned, so it'll be accepted right away.
+            runWithCaller(LAUNCHER_1, USER_0, () -> {
+                assertWith(getShortcutAsLauncher(USER_0))
+                        .selectByIds("ms3")
+                        .areAllEnabled()
+                        .areAllNotDynamic()
+                        .areAllPinned()
+                        .areAllMutable()
+                        .forAllShortcuts(si -> {
+                            assertEquals("new-title-3", si.getShortLabel());
+                            // The new one replaces the old manifest shortcut, so the long label
+                            // should be gone now.
+                            assertNull(si.getLongLabel());
+                        });
+            });
+
+            // Now, change the launcher to launcher2, and request pin again.
+            setDefaultLauncher(USER_0, mMainActivityFetcher.apply(LAUNCHER_2, USER_0));
+
+            reset(mServiceContext);
+
+            assertTrue(mManager.isRequestPinShortcutSupported());
+            mManager.requestPinShortcut(
+                    makeShortcutWithShortLabel("ms4", "new-title-4"),
+                    /*PendingIntent=*/ null);
+
+            // Initially there should be no pinned shortcuts for L2.
+            runWithCaller(LAUNCHER_2, USER_0, () -> {
+                assertWith(getShortcutAsLauncher(USER_0))
+                        .selectPinned()
+                        .isEmpty();
+
+                final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
+
+                verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+
+                assertEquals(LauncherApps.ACTION_CONFIRM_PIN_SHORTCUT,
+                        intent.getValue().getAction());
+                assertEquals(LAUNCHER_2, intent.getValue().getComponent().getPackageName());
+
+                // Check the request object.
+                final PinItemRequest request = mLauncherApps.getPinItemRequest(intent.getValue());
+
+                assertNotNull(request);
+                assertEquals(PinItemRequest.REQUEST_TYPE_SHORTCUT, request.getRequestType());
+
+                assertWith(request.getShortcutInfo())
+                        .haveIds("ms4")
+                        .areAllOrphan()
+                        .forAllShortcuts(si -> {
+                            assertEquals("new-title-4", si.getShortLabel());
+                            // The new one replaces the old manifest shortcut, so the long label
+                            // should be gone now.
+                            assertNull(si.getLongLabel());
+                        });
+                assertTrue(request.accept());
+
+                assertWith(getShortcutAsLauncher(USER_0))
+                        .selectPinned()
+                        .haveIds("ms4")
+                        .areAllEnabled();
+            });
+        });
+    }
+
+    /**
+     * Test for restoring the pre-P backup format.
+     */
+    public void testBackupAndRestore_api27format() throws Exception {
+        final byte[] payload = readTestAsset("shortcut/shortcut_api27_backup.xml").getBytes();
+
+        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "22222");
+        addPackage(LAUNCHER_1, LAUNCHER_UID_1, 10, "11111");
+
+        runWithSystemUid(() -> mService.applyRestore(payload, USER_0));
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertWith(getCallerShortcuts())
+                    .areAllPinned()
+                    .haveIds("s1")
+                    .areAllEnabled();
+        });
+
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            assertWith(getShortcutAsLauncher(USER_0))
+                    .areAllPinned()
+                    .haveIds("s1")
+                    .areAllEnabled();
+        });
+        // Make sure getBackupSourceVersionCode and isBackupSourceBackupAllowed
+        // are correct. We didn't have them in the old format.
+        assertEquals(8, mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
+                .getPackageInfo().getBackupSourceVersionCode());
+        assertTrue(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
+                .getPackageInfo().isBackupSourceBackupAllowed());
+
+        assertEquals(9, mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
+                .getPackageInfo().getBackupSourceVersionCode());
+        assertTrue(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
+                .getPackageInfo().isBackupSourceBackupAllowed());
+
+    }
+
     public void testSaveAndLoad_crossProfile() {
         prepareCrossProfileDataSet();
 
@@ -6048,7 +6422,7 @@
 
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
-                R.xml.shortcut_5);
+                R.xml.shortcut_5_altalt);
         updatePackageVersion(CALLING_PACKAGE_2, 1);
                 mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
@@ -6090,6 +6464,8 @@
                 mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
 
+        dumpsysOnLogcat("After updating package 2");
+
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
                     mManager.getManifestShortcuts()))),
@@ -6110,11 +6486,27 @@
                     "ms2", "ms3");
             // ms3 is no longer in manifest, so should be disabled.
             // but ms1 and ms2 should be enabled.
-            assertAllEnabled(list(getCallerShortcut("ms1")));
-            assertAllEnabled(list(getCallerShortcut("ms2")));
-            assertAllDisabled(list(getCallerShortcut("ms3")));
+            assertWith(getCallerShortcuts())
+                    .selectByIds("ms1", "ms2")
+                    .areAllEnabled()
+
+                    .revertToOriginalList()
+                    .selectByIds("ms3")
+                    .areAllDisabled()
+                    .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_APP_CHANGED);
         });
 
+        // Make sure the launcher see the correct disabled reason.
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            assertWith(getShortcutAsLauncher(USER_0))
+                    .forShortcutWithId("ms3", si -> {
+                        assertEquals("string-com.android.test.2-user:0-res:"
+                                        + R.string.shortcut_disabled_message3 + "/en",
+                                si.getDisabledMessage());
+                    });
+        });
+
+
         // Package 2 on user 10 has no shortcuts yet.
         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
             assertEmpty(mManager.getManifestShortcuts());
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 3220ea9..fcdadac 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -1131,7 +1131,8 @@
         assertEquals(0, si.getRank());
         assertEquals(1, si.getExtras().getInt("k"));
 
-        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
+        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED
+                | ShortcutInfo.FLAG_SHADOW , si.getFlags());
         assertNull(si.getBitmapPath()); // No icon.
         assertEquals(0, si.getIconResourceId());
 
@@ -1198,7 +1199,8 @@
         assertEquals(0, si.getRank());
         assertEquals(1, si.getExtras().getInt("k"));
 
-        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
+        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED
+                | ShortcutInfo.FLAG_SHADOW , si.getFlags());
         assertNull(si.getBitmapPath()); // No icon.
         assertEquals(0, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index d362c3b..27c5eab 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -348,20 +348,17 @@
      */
     @Test
     public void testPinnedStackLocation() {
-        createStackControllerOnStackOnDisplay(
-                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
-        final int initialStackCount = mDisplayContent.getStackCount();
-        // Ensure that the pinned stack was placed at the end
-        assertEquals(initialStackCount - 1,
-                mDisplayContent.getStackPosition(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD));
+        final TaskStack pinnedStack = createStackControllerOnStackOnDisplay(
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
+        // Ensure that the pinned stack is the top stack
+        assertEquals(pinnedStack, mDisplayContent.getPinnedStack());
+        assertEquals(pinnedStack, mDisplayContent.getTopStack());
         // By default, this should try to create a new stack on top
-        createTaskStackOnDisplay(mDisplayContent);
-        final int afterStackCount = mDisplayContent.getStackCount();
-        // Make sure the stack count has increased
-        assertEquals(initialStackCount + 1, afterStackCount);
+        final TaskStack otherStack = createTaskStackOnDisplay(mDisplayContent);
+        // Ensure that the other stack is on the display.
+        assertEquals(mDisplayContent, otherStack.getDisplayContent());
         // Ensure that the pinned stack is still on top
-        assertEquals(afterStackCount - 1,
-                mDisplayContent.getStackPosition(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD));
+        assertEquals(pinnedStack, mDisplayContent.getTopStack());
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
index 536a504..71bcae7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -16,19 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-
-import android.content.res.Configuration;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.Before;
-import org.junit.After;
-
-import android.graphics.Rect;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -36,6 +24,15 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.After;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
 /**
  * Tests for the {@link DisplayContent.TaskStackContainers} container in {@link DisplayContent}.
  *
@@ -52,12 +49,8 @@
     @Before
     public void setUp() throws Exception {
         super.setUp();
-        final Configuration overrideConfig = new Configuration();
-        overrideConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_PINNED);
-        mPinnedStack = new StackWindowController(PINNED_STACK_ID, null,
-                mDisplayContent.getDisplayId(), true /* onTop */, new Rect(), sWm).mContainer;
-        mPinnedStack.onOverrideConfigurationChanged(overrideConfig);
-
+        mPinnedStack = createStackControllerOnStackOnDisplay(
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
         // Stack should contain visible app window to be considered visible.
         final Task pinnedTask = createTaskInStack(mPinnedStack, 0 /* userId */);
         assertFalse(mPinnedStack.isVisible());
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 4e810f2..56a3fb0 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -36,8 +36,6 @@
 import android.view.IWindow;
 import android.view.WindowManager;
 
-import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.AppOpsManager.OP_NONE;
 import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
@@ -70,7 +68,7 @@
     // make sure we don't collide with any existing display. If we run into no other display, the
     // added display should be treated as default. This cannot be the default display
     private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
-    private static int sNextStackId = FIRST_DYNAMIC_STACK_ID;
+    static int sNextStackId = 1000;
 
     private static boolean sOneTimeSetupDone = false;
     DisplayContent mDisplayContent;
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 926a606..99eb846 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -22,6 +22,7 @@
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 
+import static org.junit.Assert.assertNotEquals;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyList;
 import static org.mockito.Matchers.anyString;
@@ -59,9 +60,7 @@
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
 import org.mockito.ArgumentMatchers;
-import org.mockito.Mockito;
 import org.mockito.hamcrest.MockitoHamcrest;
 
 import java.io.BufferedReader;
@@ -898,11 +897,14 @@
 
         public ShortcutListAsserter areAllEnabled() {
             forAllShortcuts(s -> assertTrue("id=" + s.getId(), s.isEnabled()));
+            areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
             return this;
         }
 
         public ShortcutListAsserter areAllDisabled() {
             forAllShortcuts(s -> assertFalse("id=" + s.getId(), s.isEnabled()));
+            forAllShortcuts(s -> assertNotEquals("id=" + s.getId(),
+                    ShortcutInfo.DISABLED_REASON_NOT_DISABLED, s.getDisabledReason()));
             return this;
         }
 
@@ -930,6 +932,16 @@
             return this;
         }
 
+        public ShortcutListAsserter areAllVisibleToPublisher() {
+            forAllShortcuts(s -> assertTrue("id=" + s.getId(), s.isVisibleToPublisher()));
+            return this;
+        }
+
+        public ShortcutListAsserter areAllNotVisibleToPublisher() {
+            forAllShortcuts(s -> assertFalse("id=" + s.getId(), s.isVisibleToPublisher()));
+            return this;
+        }
+
         public ShortcutListAsserter areAllWithKeyFieldsOnly() {
             forAllShortcuts(s -> assertTrue("id=" + s.getId(), s.hasKeyFieldsOnly()));
             return this;
@@ -960,6 +972,17 @@
             return this;
         }
 
+        public ShortcutListAsserter areAllWithDisabledReason(int disabledReason) {
+            forAllShortcuts(s -> assertEquals("id=" + s.getId(),
+                    disabledReason, s.getDisabledReason()));
+            if (disabledReason >= ShortcutInfo.DISABLED_REASON_VERSION_LOWER) {
+                areAllNotVisibleToPublisher();
+            } else {
+                areAllVisibleToPublisher();
+            }
+            return this;
+        }
+
         public ShortcutListAsserter forAllShortcuts(Consumer<ShortcutInfo> sa) {
             boolean found = false;
             for (int i = 0; i < mList.size(); i++) {
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index acc27be..d359b70 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -132,7 +132,9 @@
         mHasMidiFeature = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI);
 
         // initial scan
-        mCardsParser.scan();
+        if (mCardsParser.scan() != AlsaCardsParser.SCANSTATUS_SUCCESS) {
+            Slog.e(TAG, "Error scanning ASLA cards file.");
+        }
     }
 
     public void systemReady() {
@@ -314,7 +316,7 @@
             return null;
         }
 
-        if (!mDevicesParser.scan()) {
+        if (mDevicesParser.scan() != AlsaDevicesParser.SCANSTATUS_SUCCESS) {
             Slog.e(TAG, "Error parsing ALSA devices file.");
             return null;
         }
@@ -530,6 +532,9 @@
     //
     // called by UsbService.dump
     public void dump(IndentingPrintWriter pw) {
+        pw.println("Parsers Scan Status:");
+        pw.println("  Cards Parser: " + mCardsParser.getScanStatus());
+        pw.println("  Devices Parser: " + mDevicesParser.getScanStatus());
         pw.println("USB Audio Devices:");
         for (UsbDevice device : mAudioDevices.keySet()) {
             pw.println("  " + device.getDeviceName() + ": " + mAudioDevices.get(device));
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index c657a1b..095fdc6 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -376,6 +376,8 @@
                 }
             }
         }
+
+        mUsbAlsaManager.dump(pw);
     }
 
     private native void monitorUsbHostBus();
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 689ce95..54f7363 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -763,6 +763,18 @@
     public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
 
     /**
+     * Some carriers will send call forwarding responses for voicemail in a format that is not 3gpp
+     * compliant, which causes issues during parsing. This causes the
+     * {@link com.android.internal.telephony.CallForwardInfo#number} to contain non-numerical
+     * characters instead of a number.
+     *
+     * If true, we will detect the non-numerical characters and replace them with "Voicemail".
+     * @hide
+     */
+    public static final String KEY_CALL_FORWARDING_MAP_NON_NUMBER_TO_VOICEMAIL_BOOL =
+            "call_forwarding_map_non_number_to_voicemail_bool";
+
+    /**
      * Determines whether conference calls are supported by a carrier.  When {@code true},
      * conference calling is supported, {@code false otherwise}.
      */
@@ -1573,6 +1585,13 @@
     public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL =
             "show_ims_registration_status_bool";
 
+    /**
+     * The flag to disable the popup dialog which warns the user of data charges.
+     * @hide
+     */
+    public static final String KEY_DISABLE_CHARGE_INDICATION_BOOL =
+            "disable_charge_indication_bool";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -1703,6 +1722,7 @@
         sDefaults.putInt(KEY_GSM_DTMF_TONE_DELAY_INT, 0);
         sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0);
         sDefaults.putInt(KEY_CDMA_DTMF_TONE_DELAY_INT, 100);
+        sDefaults.putBoolean(KEY_CALL_FORWARDING_MAP_NON_NUMBER_TO_VOICEMAIL_BOOL, false);
         sDefaults.putInt(KEY_CDMA_3WAYCALL_FLASH_DELAY_INT , 0);
         sDefaults.putBoolean(KEY_SUPPORT_CONFERENCE_CALL_BOOL, true);
         sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_CALL_BOOL, true);
@@ -1840,6 +1860,7 @@
         sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null);
         sDefaults.putStringArray(KEY_ROAMING_OPERATOR_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
+        sDefaults.putBoolean(KEY_DISABLE_CHARGE_INDICATION_BOOL, false);
     }
 
     /**
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index 764b7b2..9a9877a 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -77,8 +77,9 @@
      * Integer extra that Android will attach to the intent supplied via
      * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}
      * Indicates the result code of the download. One of
-     * {@link #RESULT_SUCCESSFUL}, {@link #RESULT_EXPIRED}, {@link #RESULT_CANCELLED}, or
-     * {@link #RESULT_IO_ERROR}.
+     * {@link #RESULT_SUCCESSFUL}, {@link #RESULT_EXPIRED}, {@link #RESULT_CANCELLED},
+     * {@link #RESULT_IO_ERROR}, {@link #RESULT_DOWNLOAD_FAILURE}, {@link #RESULT_OUT_OF_STORAGE},
+     * {@link #RESULT_SERVICE_ID_NOT_DEFINED}, or {@link #RESULT_FILE_ROOT_UNREACHABLE}.
      *
      * This extra may also be used by the middleware when it is sending intents to the app.
      */
@@ -142,11 +143,41 @@
 
     /**
      * Indicates that the download will not be completed due to an I/O error incurred while
-     * writing to temp files. This commonly indicates that the device is out of storage space,
-     * but may indicate other conditions as well (such as an SD card being removed).
+     * writing to temp files.
+     *
+     * This is likely a transient error and another {@link DownloadRequest} should be sent to try
+     * the download again.
      */
     public static final int RESULT_IO_ERROR = 4;
-    // TODO - more results!
+
+    /**
+     * Indicates that the Service ID specified in the {@link DownloadRequest} is incorrect due to
+     * the Id being incorrect, stale, expired, or similar.
+     */
+    public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5;
+
+    /**
+     * Indicates that there was an error while processing downloaded files, such as a file repair or
+     * file decoding error and is not due to a file I/O error.
+     *
+     * This is likely a transient error and another {@link DownloadRequest} should be sent to try
+     * the download again.
+     */
+    public static final int RESULT_DOWNLOAD_FAILURE = 6;
+
+    /**
+     * Indicates that the file system is full and the {@link DownloadRequest} can not complete.
+     * Either space must be made on the current file system or the temp file root location must be
+     * changed to a location that is not full to download the temp files.
+     */
+    public static final int RESULT_OUT_OF_STORAGE = 7;
+
+    /**
+     * Indicates that the file root that was set is currently unreachable. This can happen if the
+     * temp files are set to be stored on external storage and the SD card was removed, for example.
+     * The temp file root should be changed before sending another DownloadRequest.
+     */
+    public static final int RESULT_FILE_ROOT_UNREACHABLE = 8;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
diff --git a/telephony/java/android/telephony/mbms/DownloadRequest.java b/telephony/java/android/telephony/mbms/DownloadRequest.java
index 5a57f32..f0d60b6 100644
--- a/telephony/java/android/telephony/mbms/DownloadRequest.java
+++ b/telephony/java/android/telephony/mbms/DownloadRequest.java
@@ -16,6 +16,7 @@
 
 package android.telephony.mbms;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.content.Intent;
 import android.net.Uri;
@@ -26,7 +27,6 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -71,6 +71,19 @@
         private String appIntent;
         private int version = CURRENT_VERSION;
 
+
+        /**
+         * Builds a new DownloadRequest.
+         * @param sourceUri the source URI for the DownloadRequest to be built. This URI should
+         *     never be null.
+         */
+        public Builder(@NonNull Uri sourceUri) {
+            if (sourceUri == null) {
+                throw new IllegalArgumentException("Source URI must be non-null.");
+            }
+            source = sourceUri;
+        }
+
         /**
          * Sets the service from which the download request to be built will download from.
          * @param serviceInfo
@@ -92,15 +105,6 @@
         }
 
         /**
-         * Sets the source URI for the download request to be built.
-         * @param source
-         */
-        public Builder setSource(Uri source) {
-            this.source = source;
-            return this;
-        }
-
-        /**
          * Set the subscription ID on which the file(s) should be downloaded.
          * @param subscriptionId
          */
@@ -316,9 +320,11 @@
             throw new RuntimeException("Could not get sha256 hash object");
         }
         if (version >= 1) {
-            // Hash the source URI, destination URI, and the app intent
+            // Hash the source URI and the app intent
             digest.update(sourceUri.toString().getBytes(StandardCharsets.UTF_8));
-            digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8));
+            if (serializedResultIntentForApp != null) {
+                digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8));
+            }
         }
         // Add updates for future versions here
         return Base64.encodeToString(digest.digest(), Base64.URL_SAFE | Base64.NO_WRAP);
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
index fe27537..9af1eb9 100644
--- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
@@ -287,7 +287,7 @@
             return;
         }
 
-        List<Uri> tempFiles = intent.getParcelableExtra(VendorUtils.EXTRA_TEMP_LIST);
+        List<Uri> tempFiles = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_LIST);
         if (tempFiles == null) {
             return;
         }
@@ -309,7 +309,7 @@
             return;
         }
         int fdCount = intent.getIntExtra(VendorUtils.EXTRA_FD_COUNT, 0);
-        List<Uri> pausedList = intent.getParcelableExtra(VendorUtils.EXTRA_PAUSED_LIST);
+        List<Uri> pausedList = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST);
 
         if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) {
             Log.i(LOG_TAG, "No temp files actually requested. Ending.");
@@ -492,9 +492,14 @@
         } catch (PackageManager.NameNotFoundException e) {
             throw new RuntimeException("Package manager couldn't find " + context.getPackageName());
         }
+        if (appInfo.metaData == null) {
+            throw new RuntimeException("App must declare the file provider authority as metadata " +
+                    "in the manifest.");
+        }
         String authority = appInfo.metaData.getString(MBMS_FILE_PROVIDER_META_DATA_KEY);
         if (authority == null) {
-            throw new RuntimeException("Must declare the file provider authority as meta data");
+            throw new RuntimeException("App must declare the file provider authority as metadata " +
+                    "in the manifest.");
         }
         return authority;
     }
diff --git a/tests/CantSaveState1/Android.mk b/tests/CantSaveState1/Android.mk
new file mode 100644
index 0000000..6e9db6e
--- /dev/null
+++ b/tests/CantSaveState1/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := CantSaveState1
+
+include $(BUILD_PACKAGE)
diff --git a/tests/CantSaveState1/AndroidManifest.xml b/tests/CantSaveState1/AndroidManifest.xml
new file mode 100644
index 0000000..fadcaeb
--- /dev/null
+++ b/tests/CantSaveState1/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.test.cantsavestate1">
+    <application android:label="Can't Save 1" android:cantSaveState="true">
+        <activity android:name="CantSave1Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/CantSaveState1/res/layout/cant_save_1_activity.xml b/tests/CantSaveState1/res/layout/cant_save_1_activity.xml
new file mode 100644
index 0000000..c5bf657
--- /dev/null
+++ b/tests/CantSaveState1/res/layout/cant_save_1_activity.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+>
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="25dp"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:text="This app #1 can't save its state"
+    />
+
+</LinearLayout>
diff --git a/cmds/statsd/src/parse_util.h b/tests/CantSaveState1/src/com/android/test/cantsavestate2/CantSave1Activity.java
similarity index 64%
copy from cmds/statsd/src/parse_util.h
copy to tests/CantSaveState1/src/com/android/test/cantsavestate2/CantSave1Activity.java
index 8b82e7b..8879ed0 100644
--- a/cmds/statsd/src/parse_util.h
+++ b/tests/CantSaveState1/src/com/android/test/cantsavestate2/CantSave1Activity.java
@@ -13,24 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef PARSE_UTIL_H
-#define PARSE_UTIL_H
 
-#include "DropboxWriter.h"
-#include "LogReader.h"
+package com.android.test.cantsavestate1;
 
-#include <log/logprint.h>
+import android.app.Activity;
+import android.os.Bundle;
 
-namespace android {
-namespace os {
-namespace statsd {
-
-EventMetricData parse(log_msg msg);
-
-int getTagId(log_msg msg);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // PARSE_UTIL_H
+public class CantSave1Activity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.cant_save_1_activity);
+    }
+}
diff --git a/tests/CantSaveState2/Android.mk b/tests/CantSaveState2/Android.mk
new file mode 100644
index 0000000..add9214
--- /dev/null
+++ b/tests/CantSaveState2/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := CantSaveState2
+
+include $(BUILD_PACKAGE)
diff --git a/tests/CantSaveState2/AndroidManifest.xml b/tests/CantSaveState2/AndroidManifest.xml
new file mode 100644
index 0000000..8f4f01d
--- /dev/null
+++ b/tests/CantSaveState2/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.test.cantsavestate2">
+    <application android:label="Can't Save 2" android:cantSaveState="true">
+        <activity android:name="CantSave2Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/CantSaveState2/res/layout/cant_save_2_activity.xml b/tests/CantSaveState2/res/layout/cant_save_2_activity.xml
new file mode 100644
index 0000000..c5b8e3d
--- /dev/null
+++ b/tests/CantSaveState2/res/layout/cant_save_2_activity.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+>
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="25dp"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:text="This app #2 can't save its state"
+    />
+
+</LinearLayout>
diff --git a/cmds/statsd/src/parse_util.h b/tests/CantSaveState2/src/com/android/test/cantsavestate2/CantSave2Activity.java
similarity index 64%
copy from cmds/statsd/src/parse_util.h
copy to tests/CantSaveState2/src/com/android/test/cantsavestate2/CantSave2Activity.java
index 8b82e7b..3ce63c7 100644
--- a/cmds/statsd/src/parse_util.h
+++ b/tests/CantSaveState2/src/com/android/test/cantsavestate2/CantSave2Activity.java
@@ -13,24 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef PARSE_UTIL_H
-#define PARSE_UTIL_H
 
-#include "DropboxWriter.h"
-#include "LogReader.h"
+package com.android.test.cantsavestate2;
 
-#include <log/logprint.h>
+import android.app.Activity;
+import android.os.Bundle;
 
-namespace android {
-namespace os {
-namespace statsd {
-
-EventMetricData parse(log_msg msg);
-
-int getTagId(log_msg msg);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // PARSE_UTIL_H
+public class CantSave2Activity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.cant_save_2_activity);
+    }
+}
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 8210403..163250d 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -296,6 +296,7 @@
                     Notification n = new Notification.Builder(NotificationTestList.this, "min")
                             .setSmallIcon(R.drawable.icon2)
                             .setContentTitle("Min priority")
+                            .setTicker("Min priority")
                             .build();
                     mNM.notify("min", 7000, n);
                 }
@@ -306,6 +307,7 @@
                     Notification n = new Notification.Builder(NotificationTestList.this, "low")
                             .setSmallIcon(R.drawable.icon2)
                             .setContentTitle("Low priority")
+                            .setTicker("Low priority")
                             .build();
                     mNM.notify("low", 7002, n);
                 }
@@ -326,6 +328,7 @@
                     Notification n = new Notification.Builder(NotificationTestList.this, "high")
                             .setSmallIcon(R.drawable.icon2)
                             .setContentTitle("High priority")
+                            .setTicker("High priority")
                             .build();
                     mNM.notify("high", 7006, n);
                 }
diff --git a/tests/net/java/android/net/IpSecManagerTest.java b/tests/net/java/android/net/IpSecManagerTest.java
index 9f31d27..ccb0f3b 100644
--- a/tests/net/java/android/net/IpSecManagerTest.java
+++ b/tests/net/java/android/net/IpSecManagerTest.java
@@ -31,19 +31,21 @@
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.system.Os;
-import android.test.AndroidTestCase;
+
 import com.android.server.IpSecService;
+
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
 
 /** Unit tests for {@link IpSecManager}. */
 @SmallTest
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
 public class IpSecManagerTest {
 
     private static final int TEST_UDP_ENCAP_PORT = 34567;
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/tests/net/java/android/net/LinkPropertiesTest.java
similarity index 80%
rename from core/tests/coretests/src/android/net/LinkPropertiesTest.java
rename to tests/net/java/android/net/LinkPropertiesTest.java
index 1cb0ecd..52da79a 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/tests/net/java/android/net/LinkPropertiesTest.java
@@ -16,19 +16,22 @@
 
 package android.net;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import android.net.IpPrefix;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.LinkProperties.CompareResult;
 import android.net.LinkProperties.ProvisioningChange;
 import android.net.RouteInfo;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.system.OsConstants;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
 import android.util.ArraySet;
 
-import junit.framework.TestCase;
-
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -37,8 +40,12 @@
 import java.util.List;
 import java.util.Set;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-public class LinkPropertiesTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LinkPropertiesTest {
     private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
     private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
             "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
@@ -92,7 +99,7 @@
         assertEquals(source.hashCode(), target.hashCode());
     }
 
-    @SmallTest
+    @Test
     public void testEqualsNull() {
         LinkProperties source = new LinkProperties();
         LinkProperties target = new LinkProperties();
@@ -101,155 +108,141 @@
         assertLinkPropertiesEqual(source, target);
     }
 
-    @SmallTest
-    public void testEqualsSameOrder() {
-        try {
-            LinkProperties source = new LinkProperties();
-            source.setInterfaceName(NAME);
-            // set 2 link addresses
-            source.addLinkAddress(LINKADDRV4);
-            source.addLinkAddress(LINKADDRV6);
-            // set 2 dnses
-            source.addDnsServer(DNS1);
-            source.addDnsServer(DNS2);
-            // set 2 gateways
-            source.addRoute(new RouteInfo(GATEWAY1));
-            source.addRoute(new RouteInfo(GATEWAY2));
-            source.setMtu(MTU);
+    @Test
+    public void testEqualsSameOrder() throws Exception {
+        LinkProperties source = new LinkProperties();
+        source.setInterfaceName(NAME);
+        // set 2 link addresses
+        source.addLinkAddress(LINKADDRV4);
+        source.addLinkAddress(LINKADDRV6);
+        // set 2 dnses
+        source.addDnsServer(DNS1);
+        source.addDnsServer(DNS2);
+        // set 2 gateways
+        source.addRoute(new RouteInfo(GATEWAY1));
+        source.addRoute(new RouteInfo(GATEWAY2));
+        source.setMtu(MTU);
 
-            LinkProperties target = new LinkProperties();
+        LinkProperties target = new LinkProperties();
 
-            // All fields are same
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
+        // All fields are same
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
 
-            assertLinkPropertiesEqual(source, target);
+        assertLinkPropertiesEqual(source, target);
 
-            target.clear();
-            // change Interface Name
-            target.setInterfaceName("qmi1");
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
-            assertFalse(source.equals(target));
+        target.clear();
+        // change Interface Name
+        target.setInterfaceName("qmi1");
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
+        assertFalse(source.equals(target));
 
-            target.clear();
-            target.setInterfaceName(NAME);
-            // change link addresses
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
-            assertFalse(source.equals(target));
+        target.clear();
+        target.setInterfaceName(NAME);
+        // change link addresses
+        target.addLinkAddress(new LinkAddress(
+                NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
+        assertFalse(source.equals(target));
 
-            target.clear();
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            // change dnses
-            target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
-            assertFalse(source.equals(target));
+        target.clear();
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        // change dnses
+        target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
+        assertFalse(source.equals(target));
 
-            target.clear();
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            // change gateway
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
-            assertFalse(source.equals(target));
+        target.clear();
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        // change gateway
+        target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
+        assertFalse(source.equals(target));
 
-            target.clear();
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            // change mtu
-            target.setMtu(1440);
-            assertFalse(source.equals(target));
-
-        } catch (Exception e) {
-            throw new RuntimeException(e.toString());
-            //fail();
-        }
+        target.clear();
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        // change mtu
+        target.setMtu(1440);
+        assertFalse(source.equals(target));
     }
 
-    @SmallTest
-    public void testEqualsDifferentOrder() {
-        try {
-            LinkProperties source = new LinkProperties();
-            source.setInterfaceName(NAME);
-            // set 2 link addresses
-            source.addLinkAddress(LINKADDRV4);
-            source.addLinkAddress(LINKADDRV6);
-            // set 2 dnses
-            source.addDnsServer(DNS1);
-            source.addDnsServer(DNS2);
-            // set 2 gateways
-            source.addRoute(new RouteInfo(GATEWAY1));
-            source.addRoute(new RouteInfo(GATEWAY2));
-            source.setMtu(MTU);
+    @Test
+    public void testEqualsDifferentOrder() throws Exception {
+        LinkProperties source = new LinkProperties();
+        source.setInterfaceName(NAME);
+        // set 2 link addresses
+        source.addLinkAddress(LINKADDRV4);
+        source.addLinkAddress(LINKADDRV6);
+        // set 2 dnses
+        source.addDnsServer(DNS1);
+        source.addDnsServer(DNS2);
+        // set 2 gateways
+        source.addRoute(new RouteInfo(GATEWAY1));
+        source.addRoute(new RouteInfo(GATEWAY2));
+        source.setMtu(MTU);
 
-            LinkProperties target = new LinkProperties();
-            // Exchange order
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV6);
-            target.addLinkAddress(LINKADDRV4);
-            target.addDnsServer(DNS2);
-            target.addDnsServer(DNS1);
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.setMtu(MTU);
+        LinkProperties target = new LinkProperties();
+        // Exchange order
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV6);
+        target.addLinkAddress(LINKADDRV4);
+        target.addDnsServer(DNS2);
+        target.addDnsServer(DNS1);
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.setMtu(MTU);
 
-            assertLinkPropertiesEqual(source, target);
-        } catch (Exception e) {
-            fail();
-        }
+        assertLinkPropertiesEqual(source, target);
     }
 
-    @SmallTest
-    public void testEqualsDuplicated() {
-        try {
-            LinkProperties source = new LinkProperties();
-            // set 3 link addresses, eg, [A, A, B]
-            source.addLinkAddress(LINKADDRV4);
-            source.addLinkAddress(LINKADDRV4);
-            source.addLinkAddress(LINKADDRV6);
+    @Test
+    public void testEqualsDuplicated() throws Exception {
+        LinkProperties source = new LinkProperties();
+        // set 3 link addresses, eg, [A, A, B]
+        source.addLinkAddress(LINKADDRV4);
+        source.addLinkAddress(LINKADDRV4);
+        source.addLinkAddress(LINKADDRV6);
 
-            LinkProperties target = new LinkProperties();
-            // set 3 link addresses, eg, [A, B, B]
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addLinkAddress(LINKADDRV6);
+        LinkProperties target = new LinkProperties();
+        // set 3 link addresses, eg, [A, B, B]
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addLinkAddress(LINKADDRV6);
 
-            assertLinkPropertiesEqual(source, target);
-        } catch (Exception e) {
-            fail();
-        }
+        assertLinkPropertiesEqual(source, target);
     }
 
     private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) {
@@ -258,7 +251,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testRouteInterfaces() {
         LinkAddress prefix = new LinkAddress(
             NetworkUtils.numericToInetAddress("2001:db8::"), 32);
@@ -317,7 +310,7 @@
         assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
     }
 
-    @SmallTest
+    @Test
     public void testStackedInterfaces() {
         LinkProperties rmnet0 = new LinkProperties();
         rmnet0.setInterfaceName("rmnet0");
@@ -373,7 +366,7 @@
         return lp.getLinkAddresses().iterator().next();
     }
 
-    @SmallTest
+    @Test
     public void testAddressMethods() {
         LinkProperties lp = new LinkProperties();
 
@@ -460,7 +453,7 @@
         assertEquals(0, lp.getLinkAddresses().size());
     }
 
-    @SmallTest
+    @Test
     public void testSetLinkAddresses() {
         LinkProperties lp = new LinkProperties();
         lp.addLinkAddress(LINKADDRV4);
@@ -475,7 +468,7 @@
         assertTrue(lp.equals(lp));
     }
 
-    @SmallTest
+    @Test
     public void testIsProvisioned() {
         LinkProperties lp4 = new LinkProperties();
         assertFalse("v4only:empty", lp4.isProvisioned());
@@ -529,7 +522,7 @@
         assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
     }
 
-    @SmallTest
+    @Test
     public void testCompareProvisioning() {
         LinkProperties v4lp = new LinkProperties();
         v4lp.addLinkAddress(LINKADDRV4);
@@ -589,8 +582,7 @@
                 LinkProperties.compareProvisioning(v6lp, v6lp2));
     }
 
-    @SmallTest
-    @Suppress  // Failing.
+    @Test
     public void testIsReachable() {
         final LinkProperties v4lp = new LinkProperties();
         assertFalse(v4lp.isReachable(DNS1));
@@ -687,7 +679,7 @@
         assertTrue(v6lp.isReachable(DNS1));
     }
 
-    @SmallTest
+    @Test
     public void testLinkPropertiesEnsureDirectlyConnectedRoutes() {
         // IPv4 case: no route added initially
         LinkProperties rmnet0 = new LinkProperties();
@@ -750,25 +742,25 @@
 
     }
 
-    @SmallTest
+    @Test
     public void testCompareResult() {
         // Either adding or removing items
-        testCompareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1),
+        compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1),
                 Arrays.asList(2, 3, 4), new ArrayList<>());
-        testCompareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4),
+        compareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4),
                 new ArrayList<>(), Arrays.asList(3, 4));
 
 
         // adding and removing items at the same time
-        testCompareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5),
+        compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5),
                 Arrays.asList(1), Arrays.asList(5));
-        testCompareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6),
+        compareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6),
                 Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));
 
         // null cases
-        testCompareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>());
-        testCompareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3));
-        testCompareResult(null, null, new ArrayList<>(), new ArrayList<>());
+        compareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>());
+        compareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3));
+        compareResult(null, null, new ArrayList<>(), new ArrayList<>());
     }
 
     private void assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual) {
@@ -780,7 +772,7 @@
         assertEquals(expectedSet, actualSet);
     }
 
-    private <T> void testCompareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved,
+    private <T> void compareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved,
             List<T> expectAdded) {
         CompareResult<T> result = new CompareResult<>(oldItems, newItems);
         assertEquals(new ArraySet<>(expectAdded), new ArraySet<>(result.added));
diff --git a/tests/net/java/android/net/NetworkStatsHistoryTest.java b/tests/net/java/android/net/NetworkStatsHistoryTest.java
index 1c0c14e..301d04d 100644
--- a/tests/net/java/android/net/NetworkStatsHistoryTest.java
+++ b/tests/net/java/android/net/NetworkStatsHistoryTest.java
@@ -32,9 +32,14 @@
 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
 import static android.text.format.DateUtils.WEEK_IN_MILLIS;
 import static android.text.format.DateUtils.YEAR_IN_MILLIS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.Suppress;
 import android.util.Log;
 
@@ -46,25 +51,31 @@
 import java.io.DataOutputStream;
 import java.util.Random;
 
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
 @SmallTest
-public class NetworkStatsHistoryTest extends AndroidTestCase {
+public class NetworkStatsHistoryTest {
     private static final String TAG = "NetworkStatsHistoryTest";
 
     private static final long TEST_START = 1194220800000L;
 
     private NetworkStatsHistory stats;
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
+    @After
+    public void tearDown() throws Exception {
         if (stats != null) {
             assertConsistent(stats);
         }
     }
 
+    @Test
     public void testReadOriginalVersion() throws Exception {
-        final DataInputStream in = new DataInputStream(
-                getContext().getResources().openRawResource(R.raw.history_v1));
+        final Context context = InstrumentationRegistry.getContext();
+        final DataInputStream in =
+                new DataInputStream(context.getResources().openRawResource(R.raw.history_v1));
 
         NetworkStatsHistory.Entry entry = null;
         try {
@@ -88,6 +99,7 @@
         }
     }
 
+    @Test
     public void testRecordSingleBucket() throws Exception {
         final long BUCKET_SIZE = HOUR_IN_MILLIS;
         stats = new NetworkStatsHistory(BUCKET_SIZE);
@@ -100,6 +112,7 @@
         assertValues(stats, 0, SECOND_IN_MILLIS, 1024L, 10L, 2048L, 20L, 2L);
     }
 
+    @Test
     public void testRecordEqualBuckets() throws Exception {
         final long bucketDuration = HOUR_IN_MILLIS;
         stats = new NetworkStatsHistory(bucketDuration);
@@ -114,6 +127,7 @@
         assertValues(stats, 1, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L);
     }
 
+    @Test
     public void testRecordTouchingBuckets() throws Exception {
         final long BUCKET_SIZE = 15 * MINUTE_IN_MILLIS;
         stats = new NetworkStatsHistory(BUCKET_SIZE);
@@ -134,6 +148,7 @@
         assertValues(stats, 2, 4 * MINUTE_IN_MILLIS, 200L, 400L, 1000L, 2000L, 20L);
     }
 
+    @Test
     public void testRecordGapBuckets() throws Exception {
         final long BUCKET_SIZE = HOUR_IN_MILLIS;
         stats = new NetworkStatsHistory(BUCKET_SIZE);
@@ -165,6 +180,7 @@
         assertValues(stats, 3, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L);
     }
 
+    @Test
     public void testRecordOverlapBuckets() throws Exception {
         final long BUCKET_SIZE = HOUR_IN_MILLIS;
         stats = new NetworkStatsHistory(BUCKET_SIZE);
@@ -182,6 +198,7 @@
         assertValues(stats, 1, (HOUR_IN_MILLIS / 2), 512L, 5L, 512L, 5L, 5L);
     }
 
+    @Test
     public void testRecordEntireGapIdentical() throws Exception {
         // first, create two separate histories far apart
         final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS);
@@ -206,6 +223,7 @@
         assertValues(stats, 3, 500L, 250L);
     }
 
+    @Test
     public void testRecordEntireOverlapVaryingBuckets() throws Exception {
         // create history just over hour bucket boundary
         final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS);
@@ -247,6 +265,7 @@
         assertValues(stats, 3, 150L, 150L);
     }
 
+    @Test
     public void testRemove() throws Exception {
         stats = new NetworkStatsHistory(HOUR_IN_MILLIS);
 
@@ -280,6 +299,7 @@
         assertEquals(0, stats.size());
     }
 
+    @Test
     public void testTotalData() throws Exception {
         final long BUCKET_SIZE = HOUR_IN_MILLIS;
         stats = new NetworkStatsHistory(BUCKET_SIZE);
@@ -304,7 +324,7 @@
 
     }
 
-    @Suppress
+    @Test
     public void testFuzzing() throws Exception {
         try {
             // fuzzing with random events, looking for crashes
@@ -341,6 +361,7 @@
         return value < 0 ? -value : value;
     }
 
+    @Test
     public void testIgnoreFields() throws Exception {
         final NetworkStatsHistory history = new NetworkStatsHistory(
                 MINUTE_IN_MILLIS, 0, FIELD_RX_BYTES | FIELD_TX_BYTES);
@@ -353,6 +374,7 @@
         assertFullValues(history, UNKNOWN, 1026L, UNKNOWN, 2050L, UNKNOWN, UNKNOWN);
     }
 
+    @Test
     public void testIgnoreFieldsRecordIn() throws Exception {
         final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL);
         final NetworkStatsHistory partial = new NetworkStatsHistory(
@@ -365,6 +387,7 @@
         assertFullValues(partial, UNKNOWN, UNKNOWN, 10L, UNKNOWN, UNKNOWN, 4L);
     }
 
+    @Test
     public void testIgnoreFieldsRecordOut() throws Exception {
         final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL);
         final NetworkStatsHistory partial = new NetworkStatsHistory(
@@ -377,6 +400,7 @@
         assertFullValues(full, MINUTE_IN_MILLIS, 0L, 10L, 0L, 0L, 4L);
     }
 
+    @Test
     public void testSerialize() throws Exception {
         final NetworkStatsHistory before = new NetworkStatsHistory(MINUTE_IN_MILLIS, 40, FIELD_ALL);
         before.recordData(0, 4 * MINUTE_IN_MILLIS,
@@ -396,6 +420,7 @@
         assertFullValues(after, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L);
     }
 
+    @Test
     public void testVarLong() throws Exception {
         assertEquals(0L, performVarLong(0L));
         assertEquals(-1L, performVarLong(-1L));
@@ -409,6 +434,7 @@
         assertEquals(Long.MAX_VALUE - 40, performVarLong(Long.MAX_VALUE - 40));
     }
 
+    @Test
     public void testIndexBeforeAfter() throws Exception {
         final long BUCKET_SIZE = HOUR_IN_MILLIS;
         stats = new NetworkStatsHistory(BUCKET_SIZE);
@@ -451,6 +477,7 @@
         assertIndexBeforeAfter(stats, 4, 4, Long.MAX_VALUE);
     }
 
+    @Test
     public void testIntersects() throws Exception {
         final long BUCKET_SIZE = HOUR_IN_MILLIS;
         stats = new NetworkStatsHistory(BUCKET_SIZE);
@@ -485,6 +512,7 @@
         assertTrue(stats.intersects(Long.MIN_VALUE, TEST_START + 1));
     }
 
+    @Test
     public void testSetValues() throws Exception {
         stats = new NetworkStatsHistory(HOUR_IN_MILLIS);
         stats.recordData(TEST_START, TEST_START + 1,
diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java
index eb85eb4..25289ba 100644
--- a/tests/net/java/android/net/NetworkStatsTest.java
+++ b/tests/net/java/android/net/NetworkStatsTest.java
@@ -30,23 +30,30 @@
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 
 import com.google.android.collect.Sets;
 
-import junit.framework.TestCase;
-
 import java.util.HashSet;
 
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
 @SmallTest
-public class NetworkStatsTest extends TestCase {
+public class NetworkStatsTest {
 
     private static final String TEST_IFACE = "test0";
     private static final String TEST_IFACE2 = "test2";
     private static final int TEST_UID = 1001;
     private static final long TEST_START = 1194220800000L;
 
+    @Test
     public void testFindIndex() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 5)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
@@ -74,6 +81,7 @@
                 ROAMING_NO));
     }
 
+    @Test
     public void testFindIndexHinted() {
         final NetworkStats stats = new NetworkStats(TEST_START, 3)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
@@ -116,6 +124,7 @@
         }
     }
 
+    @Test
     public void testAddEntryGrow() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 4);
 
@@ -168,6 +177,7 @@
                 ROAMING_YES, 7L, 70L, 5L, 50L, 11);
     }
 
+    @Test
     public void testCombineExisting() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 10);
 
@@ -190,6 +200,7 @@
                 256L, 2L, 256L, 2L, 6);
     }
 
+    @Test
     public void testSubtractIdenticalData() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
@@ -208,6 +219,7 @@
                 0L, 0L, 0L, 0);
     }
 
+    @Test
     public void testSubtractIdenticalRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
@@ -226,6 +238,7 @@
                 1L, 4L, 1L, 8);
     }
 
+    @Test
     public void testSubtractNewRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
@@ -247,6 +260,7 @@
                 1024L, 8L, 1024L, 8L, 20);
     }
 
+    @Test
     public void testSubtractMissingRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
@@ -264,6 +278,7 @@
         assertEquals(4L, result.getTotalBytes());
     }
 
+    @Test
     public void testTotalBytes() throws Exception {
         final NetworkStats iface = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
@@ -304,6 +319,7 @@
         assertEquals(96L, uidRoaming.getTotalBytes());
     }
 
+    @Test
     public void testGroupedByIfaceEmpty() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 3);
         final NetworkStats grouped = uidStats.groupedByIface();
@@ -312,6 +328,7 @@
         assertEquals(0, grouped.size());
     }
 
+    @Test
     public void testGroupedByIfaceAll() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
                 .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L, 0L,
@@ -329,6 +346,7 @@
                 384L, 24L, 0L, 6L, 0L);
     }
 
+    @Test
     public void testGroupedByIface() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
@@ -357,6 +375,7 @@
                 1024L, 64L, 0L, 0L, 0L);
     }
 
+    @Test
     public void testAddAllValues() {
         final NetworkStats first = new NetworkStats(TEST_START, 5)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
@@ -387,6 +406,7 @@
                 32L, 0L, 0L, 0L, 0L);
     }
 
+    @Test
     public void testGetTotal() {
         final NetworkStats stats = new NetworkStats(TEST_START, 7)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
@@ -415,6 +435,7 @@
         assertValues(stats.getTotal(null, ifaces), 1024L, 64L, 0L, 0L, 0L);
     }
 
+    @Test
     public void testWithoutUid() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 3)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
@@ -433,6 +454,7 @@
                 8L, 0L, 0L, 0L);
     }
 
+    @Test
     public void testClone() throws Exception {
         final NetworkStats original = new NetworkStats(TEST_START, 5)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
@@ -449,6 +471,7 @@
         assertEquals(128L + 512L, clone.getTotalBytes());
     }
 
+    @Test
     public void testAddWhenEmpty() throws Exception {
         final NetworkStats red = new NetworkStats(TEST_START, -1);
         final NetworkStats blue = new NetworkStats(TEST_START, 5)
@@ -459,6 +482,7 @@
         red.combineAllValues(blue);
     }
 
+    @Test
     public void testMigrateTun() throws Exception {
         final int tunUid = 10030;
         final String tunIface = "tun0";
@@ -556,6 +580,7 @@
     // interface by the vpn app before it's sent out of the underlying interface. The VPN app should
     // not be charged for the echoed data but it should still be charged for any extra data it sends
     // via the underlying interface.
+    @Test
     public void testMigrateTun_VpnAsLoopback() {
         final int tunUid = 10030;
         final String tunIface = "tun0";
diff --git a/core/tests/coretests/src/android/net/NetworkTest.java b/tests/net/java/android/net/NetworkTest.java
similarity index 89%
rename from core/tests/coretests/src/android/net/NetworkTest.java
rename to tests/net/java/android/net/NetworkTest.java
index 74b6d98..bacf986 100644
--- a/core/tests/coretests/src/android/net/NetworkTest.java
+++ b/tests/net/java/android/net/NetworkTest.java
@@ -16,13 +16,17 @@
 
 package android.net;
 
-import static android.test.MoreAsserts.assertNotEqual;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
 import android.net.Network;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -32,13 +36,17 @@
 import java.net.InetAddress;
 import java.net.Inet6Address;
 import java.net.SocketException;
+import java.util.Objects;
 
-import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-public class NetworkTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetworkTest {
     final Network mNetwork = new Network(99);
 
-    @SmallTest
+    @Test
     public void testBindSocketOfInvalidFdThrows() throws Exception {
 
         final FileDescriptor fd = new FileDescriptor();
@@ -50,7 +58,7 @@
         } catch (SocketException expected) {}
     }
 
-    @SmallTest
+    @Test
     public void testBindSocketOfNonSocketFdThrows() throws Exception {
         final File devNull = new File("/dev/null");
         assertTrue(devNull.canRead());
@@ -65,7 +73,7 @@
         } catch (SocketException expected) {}
     }
 
-    @SmallTest
+    @Test
     public void testBindSocketOfConnectedDatagramSocketThrows() throws Exception {
         final DatagramSocket mDgramSocket = new DatagramSocket(0, (InetAddress) Inet6Address.ANY);
         mDgramSocket.connect((InetAddress) Inet6Address.LOOPBACK, 53);
@@ -77,7 +85,7 @@
         } catch (SocketException expected) {}
     }
 
-    @SmallTest
+    @Test
     public void testBindSocketOfLocalSocketThrows() throws Exception {
         final LocalSocket mLocalClient = new LocalSocket();
         mLocalClient.bind(new LocalSocketAddress("testClient"));
@@ -98,7 +106,7 @@
         } catch (SocketException expected) {}
     }
 
-    @SmallTest
+    @Test
     public void testZeroIsObviousForDebugging() {
         Network zero = new Network(0);
         assertEquals(0, zero.hashCode());
@@ -106,7 +114,7 @@
         assertEquals("0", zero.toString());
     }
 
-    @SmallTest
+    @Test
     public void testGetNetworkHandle() {
         Network one = new Network(1);
         Network two = new Network(2);
@@ -143,4 +151,8 @@
         assertEquals(8606370526L, two.getNetworkHandle());
         assertEquals(12901337822L, three.getNetworkHandle());
     }
+
+    private static <T> void assertNotEqual(T t1, T t2) {
+        assertFalse(Objects.equals(t1, t2));
+    }
 }
diff --git a/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java b/tests/net/java/android/net/StaticIpConfigurationTest.java
similarity index 89%
rename from core/tests/coretests/src/android/net/StaticIpConfigurationTest.java
rename to tests/net/java/android/net/StaticIpConfigurationTest.java
index 59f780f..5bb5734 100644
--- a/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java
+++ b/tests/net/java/android/net/StaticIpConfigurationTest.java
@@ -16,22 +16,26 @@
 
 package android.net;
 
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-import android.net.StaticIpConfiguration;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
 import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 
 import java.net.InetAddress;
 import java.util.HashSet;
+import java.util.Objects;
 
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-import static org.junit.Assert.*;
-
-
-public class StaticIpConfigurationTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class StaticIpConfigurationTest {
 
     private static final String ADDRSTR = "192.0.2.2/25";
     private static final LinkAddress ADDR = new LinkAddress(ADDRSTR);
@@ -53,16 +57,8 @@
         assertEquals(0, s.dnsServers.size());
     }
 
-    private boolean isEqual(StaticIpConfiguration s1, StaticIpConfiguration s2) {
-        return s1.equals(s2);
-    }
-
-    private void assertEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) {
-        assertTrue(isEqual(s1, s2));
-    }
-
-    private void assertNotEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) {
-        assertFalse(isEqual(s1, s2));
+    private static <T> void assertNotEquals(T t1, T t2) {
+        assertFalse(Objects.equals(t1, t2));
     }
 
     private StaticIpConfiguration makeTestObject() {
@@ -76,13 +72,13 @@
         return s;
     }
 
-    @SmallTest
+    @Test
     public void testConstructor() {
         StaticIpConfiguration s = new StaticIpConfiguration();
         checkEmpty(s);
     }
 
-    @SmallTest
+    @Test
     public void testCopyAndClear() {
         StaticIpConfiguration empty = new StaticIpConfiguration((StaticIpConfiguration) null);
         checkEmpty(empty);
@@ -94,7 +90,7 @@
         assertEquals(empty, s2);
     }
 
-    @SmallTest
+    @Test
     public void testHashCodeAndEquals() {
         HashSet<Integer> hashCodes = new HashSet();
         hashCodes.add(0);
@@ -143,7 +139,7 @@
         assertNotEquals(s, s2);
     }
 
-    @SmallTest
+    @Test
     public void testToLinkProperties() {
         LinkProperties expected = new LinkProperties();
         expected.setInterfaceName(IFACE);
@@ -215,11 +211,10 @@
         return s2;
     }
 
-    @SmallTest
+    @Test
     public void testParceling() {
         StaticIpConfiguration s = makeTestObject();
         StaticIpConfiguration s2 = passThroughParcel(s);
         assertEquals(s, s2);
     }
 }
-
diff --git a/tests/net/java/android/net/UidRangeTest.java b/tests/net/java/android/net/UidRangeTest.java
index 0a56e1b..1d1013e 100644
--- a/tests/net/java/android/net/UidRangeTest.java
+++ b/tests/net/java/android/net/UidRangeTest.java
@@ -16,14 +16,20 @@
 
 package android.net;
 
-import android.os.Parcel;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
 import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
-public class UidRangeTest extends TestCase {
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UidRangeTest {
 
     static {
         System.loadLibrary("frameworksnettestsjni");
@@ -33,7 +39,7 @@
     private static native int getStart(byte[] inParcel);
     private static native int getStop(byte[] inParcel);
 
-    @SmallTest
+    @Test
     public void testNativeParcelUnparcel() {
         UidRange original = new UidRange(1234, Integer.MAX_VALUE);
 
@@ -45,7 +51,7 @@
         assertArrayEquals(inParcel, outParcel);
     }
 
-    @SmallTest
+    @Test
     public void testIndividualNativeFields() {
         UidRange original = new UidRange(0x11115678, 0x22224321);
         byte[] originalBytes = marshall(original);
@@ -54,14 +60,14 @@
         assertEquals(original.stop, getStop(originalBytes));
     }
 
-    @SmallTest
+    @Test
     public void testSingleItemUidRangeAllowed() {
         new UidRange(123, 123);
         new UidRange(0, 0);
         new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE);
     }
 
-    @SmallTest
+    @Test
     public void testNegativeUidsDisallowed() {
         try {
             new UidRange(-2, 100);
@@ -76,7 +82,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testStopLessThanStartDisallowed() {
         final int x = 4195000;
         try {
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index 5008a41..99a2ad9 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -16,6 +16,16 @@
 
 package android.net.apf;
 
+import static android.system.OsConstants.*;
+import static com.android.internal.util.BitUtils.bytesToBEInt;
+import static com.android.internal.util.BitUtils.put;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
+
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.NetworkUtils;
@@ -30,23 +40,22 @@
 import android.os.ConditionVariable;
 import android.os.Parcelable;
 import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.test.AndroidTestCase;
 import android.text.format.DateUtils;
-import android.test.suitebuilder.annotation.SmallTest;
-import static android.system.OsConstants.*;
 
 import com.android.frameworks.tests.net.R;
 import com.android.internal.util.HexDump;
-import static com.android.internal.util.BitUtils.bytesToBEInt;
-import static com.android.internal.util.BitUtils.put;
 
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.verify;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -69,14 +78,15 @@
  * Build, install and run with:
  *  runtest frameworks-net -c android.net.apf.ApfTest
  */
-public class ApfTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ApfTest {
     private static final int TIMEOUT_MS = 500;
 
     @Mock IpConnectivityLog mLog;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         MockitoAnnotations.initMocks(this);
         // Load up native shared library containing APF interpreter exposed via JNI.
         System.loadLibrary("frameworksnettestsjni");
@@ -161,7 +171,7 @@
      * generating bytecode for that program and running it through the
      * interpreter to verify it functions correctly.
      */
-    @SmallTest
+    @Test
     public void testApfInstructions() throws IllegalInstructionException {
         // Empty program should pass because having the program counter reach the
         // location immediately after the program indicates the packet should be
@@ -569,7 +579,7 @@
      * Generate some BPF programs, translate them to APF, then run APF and BPF programs
      * over packet traces and verify both programs filter out the same packets.
      */
-    @SmallTest
+    @Test
     public void testApfAgainstBpf() throws Exception {
         String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
                 "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
@@ -739,7 +749,7 @@
     private static final byte[] ANOTHER_IPV4_ADDR        = {10, 0, 0, 2};
     private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
 
-    @SmallTest
+    @Test
     public void testApfFilterIPv4() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
@@ -796,7 +806,7 @@
         apfFilter.shutdown();
     }
 
-    @SmallTest
+    @Test
     public void testApfFilterIPv6() throws Exception {
         final int[] ethTypeBlackList = {};
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
@@ -830,7 +840,7 @@
         apfFilter.shutdown();
     }
 
-    @SmallTest
+    @Test
     public void testApfFilterMulticast() throws Exception {
         final byte[] unicastIpv4Addr   = {(byte)192,0,2,63};
         final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
@@ -922,7 +932,7 @@
         apfFilter.shutdown();
     }
 
-    @SmallTest
+    @Test
     public void testApfFilter802_3() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
@@ -973,7 +983,7 @@
         apfFilter.shutdown();
     }
 
-    @SmallTest
+    @Test
     public void testApfFilterEthTypeBL() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
@@ -1058,7 +1068,7 @@
         assertDrop(program, garpReply());
     }
 
-    @SmallTest
+    @Test
     public void testApfFilterArp() throws Exception {
         final int[] ethTypeBlackList = {};
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
@@ -1136,7 +1146,7 @@
 
     // Test that when ApfFilter is shown the given packet, it generates a program to filter it
     // for the given lifetime.
-    private void testRaLifetime(TestApfFilter apfFilter, MockIpManagerCallback ipManagerCallback,
+    private void verifyRaLifetime(TestApfFilter apfFilter, MockIpManagerCallback ipManagerCallback,
             ByteBuffer packet, int lifetime) throws IOException, ErrnoException {
         // Verify new program generated if ApfFilter witnesses RA
         ipManagerCallback.resetApfProgramWait();
@@ -1181,7 +1191,7 @@
         ipManagerCallback.assertNoProgramUpdate();
     }
 
-    @SmallTest
+    @Test
     public void testApfFilterRa() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         final int[] ethTypeBlackList = {};
@@ -1212,7 +1222,7 @@
         basePacket.put(IPV6_ALL_NODES_ADDRESS);
         assertPass(program, basePacket.array());
 
-        testRaLifetime(apfFilter, ipManagerCallback, basePacket, ROUTER_LIFETIME);
+        verifyRaLifetime(apfFilter, ipManagerCallback, basePacket, ROUTER_LIFETIME);
         verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, -1));
 
         ByteBuffer newFlowLabelPacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
@@ -1247,7 +1257,8 @@
         prefixOptionPacket.putInt(
                 ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
                 PREFIX_VALID_LIFETIME);
-        testRaLifetime(apfFilter, ipManagerCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
+        verifyRaLifetime(
+                apfFilter, ipManagerCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
         verifyRaEvent(new RaEvent(
                 ROUTER_LIFETIME, PREFIX_VALID_LIFETIME, PREFIX_PREFERRED_LIFETIME, -1, -1, -1));
 
@@ -1259,7 +1270,7 @@
         rdnssOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
         rdnssOptionPacket.putInt(
                 ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, RDNSS_LIFETIME);
-        testRaLifetime(apfFilter, ipManagerCallback, rdnssOptionPacket, RDNSS_LIFETIME);
+        verifyRaLifetime(apfFilter, ipManagerCallback, rdnssOptionPacket, RDNSS_LIFETIME);
         verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, RDNSS_LIFETIME, -1));
 
         ByteBuffer routeInfoOptionPacket = ByteBuffer.wrap(
@@ -1270,7 +1281,7 @@
         routeInfoOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
         routeInfoOptionPacket.putInt(
                 ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, ROUTE_LIFETIME);
-        testRaLifetime(apfFilter, ipManagerCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
+        verifyRaLifetime(apfFilter, ipManagerCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
         verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, ROUTE_LIFETIME, -1, -1));
 
         ByteBuffer dnsslOptionPacket = ByteBuffer.wrap(
@@ -1281,7 +1292,7 @@
         dnsslOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
         dnsslOptionPacket.putInt(
                 ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, DNSSL_LIFETIME);
-        testRaLifetime(apfFilter, ipManagerCallback, dnsslOptionPacket, ROUTER_LIFETIME);
+        verifyRaLifetime(apfFilter, ipManagerCallback, dnsslOptionPacket, ROUTER_LIFETIME);
         verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, DNSSL_LIFETIME));
 
         // Verify that current program filters all five RAs:
@@ -1301,12 +1312,12 @@
      * copy that resource into the app's data directory and return the path to it.
      */
     private String stageFile(int rawId) throws Exception {
-        File file = new File(getContext().getFilesDir(), "staged_file");
+        File file = new File(InstrumentationRegistry.getContext().getFilesDir(), "staged_file");
         new File(file.getParent()).mkdirs();
         InputStream in = null;
         OutputStream out = null;
         try {
-            in = getContext().getResources().openRawResource(rawId);
+            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
             out = new FileOutputStream(file);
             Streams.copy(in, out);
         } finally {
@@ -1323,7 +1334,7 @@
         buffer.position(original);
     }
 
-    @SmallTest
+    @Test
     public void testRaParsing() throws Exception {
         final int maxRandomPacketSize = 512;
         final Random r = new Random();
@@ -1343,7 +1354,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testRaProcessing() throws Exception {
         final int maxRandomPacketSize = 512;
         final Random r = new Random();
@@ -1383,7 +1394,7 @@
     private native static boolean compareBpfApf(String filter, String pcap_filename,
             byte[] apf_program);
 
-    @SmallTest
+    @Test
     public void testBroadcastAddress() throws Exception {
         assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0));
         assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32));
diff --git a/tests/net/java/android/net/dhcp/DhcpPacketTest.java b/tests/net/java/android/net/dhcp/DhcpPacketTest.java
index d79c312..050183c 100644
--- a/tests/net/java/android/net/dhcp/DhcpPacketTest.java
+++ b/tests/net/java/android/net/dhcp/DhcpPacketTest.java
@@ -16,23 +16,36 @@
 
 package android.net.dhcp;
 
+import static android.net.dhcp.DhcpPacket.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import android.net.DhcpResults;
 import android.net.LinkAddress;
 import android.net.NetworkUtils;
 import android.net.metrics.DhcpErrorEvent;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.system.OsConstants;
-import android.test.suitebuilder.annotation.SmallTest;
+
 import com.android.internal.util.HexDump;
+
 import java.net.Inet4Address;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Random;
-import junit.framework.TestCase;
 
-import static android.net.dhcp.DhcpPacket.*;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-public class DhcpPacketTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DhcpPacketTest {
 
     private static Inet4Address SERVER_ADDR = v4Address("192.0.2.1");
     private static Inet4Address CLIENT_ADDR = v4Address("192.0.2.234");
@@ -46,6 +59,7 @@
         return (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
     }
 
+    @Before
     public void setUp() {
         DhcpPacket.testOverrideVendorId = "android-dhcp-???";
         DhcpPacket.testOverrideHostname = "android-01234567890abcde";
@@ -131,7 +145,7 @@
         assertEquals(expectedVendorInfo, offerPacket.mVendorInfo);
     }
 
-    @SmallTest
+    @Test
     public void testDomainName() throws Exception {
         byte[] nullByte = new byte[] { 0x00 };
         byte[] twoNullBytes = new byte[] { 0x00, 0x00 };
@@ -186,7 +200,7 @@
         assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis());
     }
 
-    @SmallTest
+    @Test
     public void testLeaseTime() throws Exception {
         byte[] noLease = null;
         byte[] tooShortLease = new byte[] { 0x00, 0x00 };
@@ -234,7 +248,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testIpAddress() throws Exception {
         byte[] slash11Netmask = new byte[] { (byte) 0xff, (byte) 0xe0, 0x00, 0x00 };
         byte[] slash24Netmask = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00 };
@@ -278,11 +292,11 @@
         assertEquals(mtu, dhcpResults.mtu);
     }
 
-    @SmallTest
+    @Test
     public void testOffer1() throws Exception {
-        // TODO: Turn all of these into golden files. This will probably require modifying
-        // Android.mk appropriately, making this into an AndroidTestCase, and adding code to read
-        // the golden files from the test APK's assets via mContext.getAssets().
+        // TODO: Turn all of these into golden files. This will probably require using
+        // android.support.test.InstrumentationRegistry for obtaining a Context object
+        // to read such golden files, along with an appropriate Android.mk.
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
             "451001480000000080118849c0a89003c0a89ff7" +
@@ -311,7 +325,7 @@
                 null, "192.168.144.3", null, 7200, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testOffer2() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
@@ -343,7 +357,7 @@
         assertTrue(dhcpResults.hasMeteredHint());
     }
 
-    @SmallTest
+    @Test
     public void testBadIpPacket() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -358,7 +372,7 @@
         fail("Dhcp packet parsing should have failed");
     }
 
-    @SmallTest
+    @Test
     public void testBadDhcpPacket() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -377,7 +391,7 @@
         fail("Dhcp packet parsing should have failed");
     }
 
-    @SmallTest
+    @Test
     public void testBadTruncatedOffer() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -406,7 +420,7 @@
         fail("Dhcp packet parsing should have failed");
     }
 
-    @SmallTest
+    @Test
     public void testBadOfferWithoutACookie() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -437,7 +451,7 @@
         fail("Dhcp packet parsing should have failed");
     }
 
-    @SmallTest
+    @Test
     public void testOfferWithBadCookie() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -473,7 +487,7 @@
         assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
     }
 
-    @SmallTest
+    @Test
     public void testTruncatedOfferPackets() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -507,7 +521,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testRandomPackets() throws Exception {
         final int maxRandomPacketSize = 512;
         final Random r = new Random();
@@ -547,7 +561,7 @@
                 null, "192.168.144.3", null, 7200, false, expectedMtu, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testMtu() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
@@ -583,7 +597,7 @@
         checkMtu(packet, 0, mtuBytes(-1));
     }
 
-    @SmallTest
+    @Test
     public void testBadHwaddrLength() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
@@ -652,7 +666,7 @@
         assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
     }
 
-    @SmallTest
+    @Test
     public void testPadAndOverloadedOptionsOffer() throws Exception {
         // A packet observed in the real world that is interesting for two reasons:
         //
@@ -691,7 +705,7 @@
                 null, "1.1.1.1", null, 43200, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testBug2111() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
@@ -721,7 +735,7 @@
                 "domain123.co.uk", "192.0.2.254", null, 49094, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testBug2136() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // Ethernet header.
@@ -754,7 +768,7 @@
                 "lancs.ac.uk", "10.32.255.128", null, 7200, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testUdpServerAnySourcePort() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // Ethernet header.
@@ -789,7 +803,7 @@
                 "wvm.edu", "10.1.105.252", null, 86400, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testUdpInvalidDstPort() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // Ethernet header.
@@ -821,7 +835,7 @@
         } catch (ParseException expected) {}
     }
 
-    @SmallTest
+    @Test
     public void testMultipleRouters() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // Ethernet header.
@@ -854,7 +868,7 @@
                 null, "192.171.189.2", null, 28800, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testDiscoverPacket() throws Exception {
         short secs = 7;
         int transactionId = 0xdeadbeef;
diff --git a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
index 5deba27..6647760 100644
--- a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
+++ b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
@@ -19,20 +19,30 @@
 import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
 import static android.net.netlink.StructNlMsgHdr.NLM_F_ACK;
 import static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import android.net.netlink.NetlinkConstants;
 import android.net.netlink.NetlinkErrorMessage;
 import android.net.netlink.NetlinkMessage;
 import android.net.netlink.StructNlMsgErr;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.util.Log;
+
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import junit.framework.TestCase;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
 import libcore.util.HexEncoding;
 
 
-public class NetlinkErrorMessageTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetlinkErrorMessageTest {
     private final String TAG = "NetlinkErrorMessageTest";
 
     // Hexadecimal representation of packet capture.
@@ -54,7 +64,7 @@
     public static final byte[] NLM_ERROR_OK =
             HexEncoding.decode(NLM_ERROR_OK_HEX.toCharArray(), false);
 
-    @SmallTest
+    @Test
     public void testParseNlmErrorOk() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(NLM_ERROR_OK);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
diff --git a/tests/net/java/android/net/netlink/NetlinkSocketTest.java b/tests/net/java/android/net/netlink/NetlinkSocketTest.java
index 78b3b70..bd36bac8 100644
--- a/tests/net/java/android/net/netlink/NetlinkSocketTest.java
+++ b/tests/net/java/android/net/netlink/NetlinkSocketTest.java
@@ -16,25 +16,35 @@
 
 package android.net.netlink;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 import android.net.netlink.NetlinkSocket;
 import android.net.netlink.RtNetlinkNeighborMessage;
 import android.net.netlink.StructNdMsg;
 import android.net.netlink.StructNlMsgHdr;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.system.ErrnoException;
 import android.system.NetlinkSocketAddress;
 import android.system.OsConstants;
 import android.util.Log;
+
 import java.io.InterruptedIOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import junit.framework.TestCase;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 
-public class NetlinkSocketTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetlinkSocketTest {
     private final String TAG = "NetlinkSocketTest";
 
-    @SmallTest
+    @Test
     public void testBasicWorkingGetNeighborsQuery() throws Exception {
         NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
         assertNotNull(s);
@@ -93,7 +103,7 @@
         s.close();
     }
 
-    @SmallTest
+    @Test
     public void testRepeatedCloseCallsAreQuiet() throws Exception {
         // Create a working NetlinkSocket.
         NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
diff --git a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
index 029758e..c9fd74f 100644
--- a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
+++ b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
@@ -16,15 +16,19 @@
 
 package android.net.netlink;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 import android.net.netlink.NetlinkConstants;
 import android.net.netlink.NetlinkMessage;
 import android.net.netlink.RtNetlinkNeighborMessage;
 import android.net.netlink.StructNdMsg;
 import android.net.netlink.StructNlMsgHdr;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.system.OsConstants;
 import android.util.Log;
-import libcore.util.HexEncoding;
 
 import java.net.Inet4Address;
 import java.net.InetAddress;
@@ -32,10 +36,15 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Arrays;
-import junit.framework.TestCase;
 
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
-public class RtNetlinkNeighborMessageTest extends TestCase {
+import libcore.util.HexEncoding;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RtNetlinkNeighborMessageTest {
     private final String TAG = "RtNetlinkNeighborMessageTest";
 
     // Hexadecimal representation of packet capture.
@@ -136,7 +145,7 @@
     public static final byte[] RTM_GETNEIGH_RESPONSE =
             HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
 
-    @SmallTest
+    @Test
     public void testParseRtmDelNeigh() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
@@ -163,7 +172,7 @@
         assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
     }
 
-    @SmallTest
+    @Test
     public void testParseRtmNewNeigh() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
@@ -190,7 +199,7 @@
         assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
     }
 
-    @SmallTest
+    @Test
     public void testParseRtmGetNeighResponse() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
@@ -215,7 +224,7 @@
         assertEquals(14, messageCount);
     }
 
-    @SmallTest
+    @Test
     public void testCreateRtmNewNeighMessage() {
         final int seqNo = 2635;
         final int ifIndex = 14;
diff --git a/tests/net/java/android/net/util/BlockingSocketReaderTest.java b/tests/net/java/android/net/util/BlockingSocketReaderTest.java
index 1aad453..29dfa4c 100644
--- a/tests/net/java/android/net/util/BlockingSocketReaderTest.java
+++ b/tests/net/java/android/net/util/BlockingSocketReaderTest.java
@@ -18,15 +18,19 @@
 
 import static android.net.util.BlockingSocketReader.DEFAULT_RECV_BUF_SIZE;
 import static android.system.OsConstants.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.StructTimeval;
 
-import libcore.io.IoBridge;
-
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -41,15 +45,21 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import junit.framework.TestCase;
+import org.junit.runner.RunWith;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
+import libcore.io.IoBridge;
 
 /**
  * Tests for BlockingSocketReader.
  *
  * @hide
  */
-public class BlockingSocketReaderTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BlockingSocketReaderTest {
     static final InetAddress LOOPBACK6 = Inet6Address.getLoopbackAddress();
     static final StructTimeval TIMEO = StructTimeval.fromMillis(500);
 
@@ -103,7 +113,7 @@
         }
     };
 
-    @Override
+    @Before
     public void setUp() {
         resetLatch();
         mLocalSocket = null;
@@ -115,7 +125,7 @@
         mHandlerThread.start();
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         if (mReceiver != null) {
             mHandlerThread.getThreadHandler().post(() -> { mReceiver.stop(); });
@@ -143,6 +153,7 @@
         sender.close();
     }
 
+    @Test
     public void testBasicWorking() throws Exception {
         final Handler h = mHandlerThread.getThreadHandler();
         mReceiver = new UdpLoopbackReader(h);
@@ -186,6 +197,7 @@
         public FileDescriptor createFd() { return null; }
     }
 
+    @Test
     public void testMinimalRecvBufSize() throws Exception {
         final Handler h = mHandlerThread.getThreadHandler();
 
diff --git a/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java b/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java
index dd679bc..38d3d74 100644
--- a/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java
+++ b/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java
@@ -17,18 +17,25 @@
 package android.net.util;
 
 import static android.net.util.NetworkConstants.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 import libcore.util.HexEncoding;
 
-import junit.framework.TestCase;
-
-
 /**
  * Tests for ConnectivityPacketSummary.
  *
  * @hide
  */
-public class ConnectivityPacketSummaryTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConnectivityPacketSummaryTest {
     private static final byte[] MYHWADDR = {
         asByte(0x80), asByte(0x7a), asByte(0xbf), asByte(0x6f), asByte(0x48), asByte(0xf3)
     };
@@ -39,6 +46,7 @@
         return ConnectivityPacketSummary.summarize(MYHWADDR, bytes);
     }
 
+    @Test
     public void testParseICMPv6DADProbe() {
         final String packet =
                 // Ethernet
@@ -60,6 +68,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseICMPv6RS() {
         final String packet =
                 // Ethernet
@@ -81,6 +90,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseICMPv6RA() {
         final String packet =
                 // Ethernet
@@ -113,6 +123,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseICMPv6NS() {
         final String packet =
                 // Ethernet
@@ -135,6 +146,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testInvalidICMPv6NDLength() {
         final String packet =
                 // Ethernet
@@ -159,6 +171,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseICMPv6NA() {
         final String packet =
                 // Ethernet
@@ -179,6 +192,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseARPRequest() {
         final String packet =
                 // Ethernet
@@ -197,6 +211,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseARPReply() {
         final String packet =
                 // Ethernet
@@ -217,6 +232,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseDHCPv4Discover() {
         final String packet =
                 // Ethernet
@@ -262,6 +278,7 @@
         assertTrue(getSummary(packet).startsWith(expectedPrefix));
     }
 
+    @Test
     public void testParseDHCPv4Offer() {
         final String packet =
                 // Ethernet
@@ -307,6 +324,7 @@
         assertTrue(getSummary(packet).startsWith(expectedPrefix));
     }
 
+    @Test
     public void testParseDHCPv4Request() {
         final String packet =
                 // Ethernet
@@ -354,6 +372,7 @@
         assertTrue(getSummary(packet).startsWith(expectedPrefix));
     }
 
+    @Test
     public void testParseDHCPv4Ack() {
         final String packet =
                 // Ethernet
diff --git a/tests/net/java/android/net/util/IpUtilsTest.java b/tests/net/java/android/net/util/IpUtilsTest.java
index c2d1608..8903bf9 100644
--- a/tests/net/java/android/net/util/IpUtilsTest.java
+++ b/tests/net/java/android/net/util/IpUtilsTest.java
@@ -16,15 +16,19 @@
 
 package android.net.util;
 
-import android.net.util.IpUtils;
-import android.test.suitebuilder.annotation.SmallTest;
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 
 import java.nio.ByteBuffer;
 
-import junit.framework.TestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
-
-public class IpUtilsTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpUtilsTest {
 
     private static final int IPV4_HEADER_LENGTH = 20;
     private static final int IPV6_HEADER_LENGTH = 40;
@@ -67,7 +71,7 @@
     //           "hello")
     // print JavaPacketDefinition(str(packet))
 
-    @SmallTest
+    @Test
     public void testIpv6TcpChecksum() throws Exception {
         // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80) /
         //           scapy.TCP(sport=12345, dport=7,
@@ -115,7 +119,7 @@
         assertEquals(0, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen));
     }
 
-    @SmallTest
+    @Test
     public void testIpv4UdpChecksum() {
         // packet = (scapy.IP(src="192.0.2.1", dst="192.0.2.2", tos=0x40) /
         //           scapy.UDP(sport=32012, dport=4500) /
diff --git a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
index a423c2a..fb2bd79 100644
--- a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -24,12 +24,15 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 import android.content.res.Resources;
 import android.net.NetworkStats;
 import android.net.TrafficStats;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
+import android.support.test.runner.AndroidJUnit4;
 
 import com.android.frameworks.tests.net.R;
 
@@ -42,19 +45,23 @@
 import libcore.io.IoUtils;
 import libcore.io.Streams;
 
+import org.junit.runner.RunWith;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
 /**
  * Tests for {@link NetworkStatsFactory}.
  */
+@RunWith(AndroidJUnit4.class)
 @SmallTest
-public class NetworkStatsFactoryTest extends AndroidTestCase {
+public class NetworkStatsFactoryTest {
     private File mTestProc;
     private NetworkStatsFactory mFactory;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-
-        mTestProc = new File(getContext().getFilesDir(), "proc");
+        mTestProc = new File(InstrumentationRegistry.getContext().getFilesDir(), "proc");
         if (mTestProc.exists()) {
             IoUtils.deleteContents(mTestProc);
         }
@@ -62,17 +69,16 @@
         mFactory = new NetworkStatsFactory(mTestProc);
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         mFactory = null;
 
         if (mTestProc.exists()) {
             IoUtils.deleteContents(mTestProc);
         }
-
-        super.tearDown();
     }
 
+    @Test
     public void testNetworkStatsDetail() throws Exception {
         final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical);
 
@@ -84,6 +90,7 @@
         assertStatsEntry(stats, "rmnet2", 10001, SET_DEFAULT, 0x0, 1125899906842624L, 984L);
     }
 
+    @Test
     public void testKernelTags() throws Exception {
         assertEquals(0, kernelToTag("0x0000000000000000"));
         assertEquals(0x32, kernelToTag("0x0000003200000000"));
@@ -98,6 +105,7 @@
         assertEquals(TrafficStats.TAG_SYSTEM_DOWNLOAD, kernelToTag("0xffffff0100000000"));
     }
 
+    @Test
     public void testNetworkStatsWithSet() throws Exception {
         final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical);
         assertEquals(70, stats.size());
@@ -106,6 +114,7 @@
         assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L);
     }
 
+    @Test
     public void testNetworkStatsSingle() throws Exception {
         stageFile(R.raw.xt_qtaguid_iface_typical, file("net/xt_qtaguid/iface_stat_all"));
 
@@ -116,6 +125,7 @@
         assertStatsEntry(stats, "test2", UID_ALL, SET_ALL, TAG_NONE, 1L, 2L, 3L, 4L);
     }
 
+    @Test
     public void testNetworkStatsXt() throws Exception {
         stageFile(R.raw.xt_qtaguid_iface_fmt_typical, file("net/xt_qtaguid/iface_stat_fmt"));
 
@@ -127,6 +137,7 @@
         assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L);
     }
 
+    @Test
     public void testDoubleClatAccounting() throws Exception {
         NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
 
@@ -161,6 +172,7 @@
         NetworkStatsFactory.noteStackedIface("v4-wlan0", null);
     }
 
+    @Test
     public void testDoubleClatAccounting100MBDownload() throws Exception {
         // Downloading 100mb from an ipv4 only destination in a foreground activity
 
@@ -197,7 +209,7 @@
         InputStream in = null;
         OutputStream out = null;
         try {
-            in = getContext().getResources().openRawResource(rawId);
+            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
             out = new FileOutputStream(file);
             Streams.copy(in, out);
         } finally {
@@ -251,5 +263,4 @@
         assertEquals("unexpected txBytes", txBytes, entry.txBytes);
         assertEquals("unexpected txPackets", txPackets, entry.txPackets);
     }
-
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 335e6240..c2cb66d 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -26,8 +26,13 @@
 import static android.net.ConnectivityManager.getNetworkTypeName;
 import static android.net.NetworkCapabilities.*;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
 import static com.android.internal.util.TestUtils.waitForIdleHandler;
-
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.eq;
@@ -87,9 +92,10 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.test.AndroidTestCase;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.mock.MockContentResolver;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
@@ -105,7 +111,11 @@
 import com.android.server.net.NetworkPinner;
 import com.android.server.net.NetworkPolicyManagerInternal;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
@@ -123,13 +133,16 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Predicate;
 
+
 /**
  * Tests for {@link ConnectivityService}.
  *
  * Build, install and run with:
  *  runtest frameworks-net -c com.android.server.ConnectivityServiceTest
  */
-public class ConnectivityServiceTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConnectivityServiceTest {
     private static final String TAG = "ConnectivityServiceTest";
 
     private static final int TIMEOUT_MS = 500;
@@ -141,6 +154,7 @@
     private MockNetworkAgent mWiFiNetworkAgent;
     private MockNetworkAgent mCellNetworkAgent;
     private MockNetworkAgent mEthernetNetworkAgent;
+    private Context mContext;
 
     // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
     // do not go through ConnectivityService but talk to netd directly, so they don't automatically
@@ -242,7 +256,7 @@
         waitForIdle(TIMEOUT_MS);
     }
 
-    @SmallTest
+    @Test
     public void testWaitForIdle() {
         final int attempts = 50;  // Causes the test to take about 200ms on bullhead-eng.
 
@@ -743,7 +757,8 @@
 
                 // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks
                 // can have odd side-effects, like network validations succeeding.
-                final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks();
+                Context context = InstrumentationRegistry.getContext();
+                final Network[] networks = ConnectivityManager.from(context).getAllNetworks();
                 boolean overlaps = false;
                 for (Network network : networks) {
                     if (netId == network.netId) {
@@ -814,9 +829,9 @@
         fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms");
     }
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
+        mContext = InstrumentationRegistry.getContext();
 
         // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
         // http://b/25897652 .
@@ -824,7 +839,7 @@
             Looper.prepare();
         }
 
-        mServiceContext = new MockContext(getContext());
+        mServiceContext = new MockContext(InstrumentationRegistry.getContext());
         LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
         LocalServices.addService(
                 NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
@@ -835,7 +850,7 @@
                 mock(IpConnectivityLog.class));
 
         mService.systemReady();
-        mCm = new WrappedConnectivityManager(getContext(), mService);
+        mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
         mCm.bindProcessToNetwork(null);
 
         // Ensure that the default setting for Captive Portals is used for most tests
@@ -843,6 +858,7 @@
         setMobileDataAlwaysOn(false);
     }
 
+    @After
     public void tearDown() throws Exception {
         setMobileDataAlwaysOn(false);
         if (mCellNetworkAgent != null) {
@@ -857,7 +873,6 @@
             mEthernetNetworkAgent.disconnect();
             mEthernetNetworkAgent = null;
         }
-        super.tearDown();
     }
 
     private static int transportToLegacyType(int transport) {
@@ -931,6 +946,7 @@
         return cv;
     }
 
+    @Test
     public void testNetworkTypes() {
         // Ensure that our mocks for the networkAttributes config variable work as expected. If they
         // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types
@@ -946,7 +962,7 @@
         assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET));
     }
 
-    @SmallTest
+    @Test
     public void testLingering() throws Exception {
         verifyNoNetwork();
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -987,7 +1003,7 @@
         verifyNoNetwork();
     }
 
-    @SmallTest
+    @Test
     public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
         // Test bringing up unvalidated WiFi
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -1022,7 +1038,7 @@
         verifyNoNetwork();
     }
 
-    @SmallTest
+    @Test
     public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
         // Test bringing up unvalidated cellular.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1048,7 +1064,7 @@
         verifyNoNetwork();
     }
 
-    @SmallTest
+    @Test
     public void testUnlingeringDoesNotValidate() throws Exception {
         // Test bringing up unvalidated WiFi.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -1076,7 +1092,7 @@
                 NET_CAPABILITY_VALIDATED));
     }
 
-    @SmallTest
+    @Test
     public void testCellularOutscoresWeakWifi() throws Exception {
         // Test bringing up validated cellular.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1102,7 +1118,7 @@
         verifyActiveNetwork(TRANSPORT_WIFI);
     }
 
-    @SmallTest
+    @Test
     public void testReapingNetwork() throws Exception {
         // Test bringing up WiFi without NET_CAPABILITY_INTERNET.
         // Expect it to be torn down immediately because it satisfies no requests.
@@ -1135,7 +1151,7 @@
         waitFor(cv);
     }
 
-    @SmallTest
+    @Test
     public void testCellularFallback() throws Exception {
         // Test bringing up validated cellular.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1173,7 +1189,7 @@
         verifyActiveNetwork(TRANSPORT_WIFI);
     }
 
-    @SmallTest
+    @Test
     public void testWiFiFallback() throws Exception {
         // Test bringing up unvalidated WiFi.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -1387,7 +1403,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testStateChangeNetworkCallbacks() throws Exception {
         final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
         final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
@@ -1477,7 +1493,7 @@
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
     }
 
-    @SmallTest
+    @Test
     public void testMultipleLingering() {
         NetworkRequest request = new NetworkRequest.Builder()
                 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED)
@@ -1705,7 +1721,7 @@
         mCm.unregisterNetworkCallback(trackDefaultCallback);
     }
 
-    @SmallTest
+    @Test
     public void testExplicitlySelected() {
         NetworkRequest request = new NetworkRequest.Builder()
                 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET)
@@ -1872,7 +1888,7 @@
         handlerThread.quit();
     }
 
-    @SmallTest
+    @Test
     public void testNetworkFactoryRequests() throws Exception {
         tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
         tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
@@ -1892,7 +1908,7 @@
         // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
     }
 
-    @SmallTest
+    @Test
     public void testNoMutableNetworkRequests() throws Exception {
         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
         NetworkRequest request1 = new NetworkRequest.Builder()
@@ -1909,7 +1925,7 @@
         assertException(() -> { mCm.requestNetwork(request2, pendingIntent); }, expected);
     }
 
-    @SmallTest
+    @Test
     public void testMMSonWiFi() throws Exception {
         // Test bringing up cellular without MMS NetworkRequest gets reaped
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1948,7 +1964,7 @@
         verifyActiveNetwork(TRANSPORT_WIFI);
     }
 
-    @SmallTest
+    @Test
     public void testMMSonCell() throws Exception {
         // Test bringing up cellular without MMS
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1977,7 +1993,7 @@
         verifyActiveNetwork(TRANSPORT_CELLULAR);
     }
 
-    @SmallTest
+    @Test
     public void testCaptivePortal() {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -2028,7 +2044,7 @@
         validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
     }
 
-    @SmallTest
+    @Test
     public void testCaptivePortalApp() {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -2074,7 +2090,7 @@
         mCm.unregisterNetworkCallback(captivePortalCallback);
     }
 
-    @SmallTest
+    @Test
     public void testAvoidOrIgnoreCaptivePortals() {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -2119,7 +2135,7 @@
         return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI);
     }
 
-    @SmallTest
+    @Test
     public void testNetworkSpecifier() {
         NetworkRequest rEmpty1 = newWifiRequestBuilder().build();
         NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build();
@@ -2180,7 +2196,7 @@
         assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cFoo, cBar);
     }
 
-    @SmallTest
+    @Test
     public void testInvalidNetworkSpecifier() {
         try {
             NetworkRequest.Builder builder = new NetworkRequest.Builder();
@@ -2241,7 +2257,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testNetworkSpecifierUidSpoofSecurityException() {
         class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
             @Override
@@ -2275,7 +2291,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testRegisterDefaultNetworkCallback() throws Exception {
         final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
         mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
@@ -2324,7 +2340,7 @@
         defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
     }
 
-    @SmallTest
+    @Test
     public void testAdditionalStateCallbacks() throws Exception {
         // File a network request for mobile.
         final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
@@ -2385,7 +2401,7 @@
         return nc.hasCapability(NET_CAPABILITY_FOREGROUND);
     }
 
-    @SmallTest
+    @Test
     public void testBackgroundNetworks() throws Exception {
         // Create a background request. We can't do this ourselves because ConnectivityService
         // doesn't have an API for it. So just turn on mobile data always on.
@@ -2554,7 +2570,7 @@
         return false;
     }
 
-    @SmallTest
+    @Test
     public void testMobileDataAlwaysOn() throws Exception {
         final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
         final NetworkRequest cellRequest = new NetworkRequest.Builder()
@@ -2619,7 +2635,7 @@
         handlerThread.quit();
     }
 
-    @SmallTest
+    @Test
     public void testAvoidBadWifiSetting() throws Exception {
         final ContentResolver cr = mServiceContext.getContentResolver();
         final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
@@ -2657,7 +2673,7 @@
         assertTrue(tracker.shouldNotifyWifiUnvalidated());
     }
 
-    @SmallTest
+    @Test
     public void testAvoidBadWifi() throws Exception {
         final ContentResolver cr = mServiceContext.getContentResolver();
         final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
@@ -2784,7 +2800,7 @@
         mCm.unregisterNetworkCallback(defaultCallback);
     }
 
-    @SmallTest
+    @Test
     public void testMeteredMultipathPreferenceSetting() throws Exception {
         final ContentResolver cr = mServiceContext.getContentResolver();
         final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
@@ -2808,7 +2824,7 @@
      * Validate that a satisfied network request does not trigger onUnavailable() once the
      * time-out period expires.
      */
-    @SmallTest
+    @Test
     public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
@@ -2828,7 +2844,7 @@
      * Validate that a satisfied network request followed by a disconnected (lost) network does
      * not trigger onUnavailable() once the time-out period expires.
      */
-    @SmallTest
+    @Test
     public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
@@ -2852,7 +2868,7 @@
      * callback is called when time-out expires. Then validate that if network request is
      * (somehow) satisfied - the callback isn't called later.
      */
-    @SmallTest
+    @Test
     public void testTimedoutNetworkRequest() {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
@@ -2873,7 +2889,7 @@
      * Validate that when a network request is unregistered (cancelled), no posterior event can
      * trigger the callback.
      */
-    @SmallTest
+    @Test
     public void testNoCallbackAfterUnregisteredNetworkRequest() {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
@@ -2981,7 +2997,7 @@
         return mWiFiNetworkAgent.getNetwork();
     }
 
-    @SmallTest
+    @Test
     public void testPacketKeepalives() throws Exception {
         InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
         InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
@@ -3105,7 +3121,7 @@
         callback3.expectStopped();
     }
 
-    @SmallTest
+    @Test
     public void testGetCaptivePortalServerUrl() throws Exception {
         String url = mCm.getCaptivePortalServerUrl();
         assertEquals("http://connectivitycheck.gstatic.com/generate_204", url);
@@ -3150,7 +3166,7 @@
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
     }
 
-    @SmallTest
+    @Test
     public void testNetworkPinner() {
         NetworkRequest wifiRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_WIFI)
@@ -3210,7 +3226,7 @@
         assertPinnedToWifiWithCellDefault();
     }
 
-    @SmallTest
+    @Test
     public void testNetworkCallbackMaximum() {
         final int MAX_REQUESTS = 100;
         final int CALLBACKS = 90;
@@ -3280,12 +3296,14 @@
             mCm.requestNetwork(networkRequest, networkCallback);
             mCm.unregisterNetworkCallback(networkCallback);
         }
+        waitForIdle();
 
         for (int i = 0; i < MAX_REQUESTS; i++) {
             NetworkCallback networkCallback = new NetworkCallback();
             mCm.registerNetworkCallback(networkRequest, networkCallback);
             mCm.unregisterNetworkCallback(networkCallback);
         }
+        waitForIdle();
 
         for (int i = 0; i < MAX_REQUESTS; i++) {
             PendingIntent pendingIntent =
@@ -3293,6 +3311,7 @@
             mCm.requestNetwork(networkRequest, pendingIntent);
             mCm.unregisterNetworkCallback(pendingIntent);
         }
+        waitForIdle();
 
         for (int i = 0; i < MAX_REQUESTS; i++) {
             PendingIntent pendingIntent =
@@ -3302,7 +3321,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testNetworkInfoOfTypeNone() {
         ConditionVariable broadcastCV = waitForConnectivityBroadcasts(1);
 
@@ -3342,7 +3361,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testDeprecatedAndUnsupportedOperations() throws Exception {
         final int TYPE_NONE = ConnectivityManager.TYPE_NONE;
         assertNull(mCm.getNetworkInfo(TYPE_NONE));
@@ -3363,7 +3382,7 @@
         assertException(() -> { mCm.requestRouteToHostAddress(TYPE_NONE, null); }, unsupported);
     }
 
-    @SmallTest
+    @Test
     public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() {
         final NetworkRequest networkRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_WIFI).build();
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index efc58cc..83ee361 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -36,6 +36,7 @@
 import android.os.Binder;
 import android.os.ParcelFileDescriptor;
 import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.system.ErrnoException;
 import android.system.Os;
 
@@ -48,11 +49,10 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
 
 /** Unit tests for {@link IpSecService}. */
 @SmallTest
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
 public class IpSecServiceTest {
 
     private static final int DROID_SPI = 0xD1201D;
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 77956be..354cf2f 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -16,24 +16,8 @@
 
 package com.android.server.connectivity;
 
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkMisc;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.format.DateUtils;
-import com.android.internal.R;
-import com.android.server.ConnectivityService;
-import com.android.server.connectivity.NetworkNotificationManager;
-import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
-import junit.framework.TestCase;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
@@ -44,7 +28,32 @@
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.reset;
 
-public class LingerMonitorTest extends TestCase {
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
+import android.net.NetworkMisc;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
+import android.text.format.DateUtils;
+
+import com.android.internal.R;
+import com.android.server.ConnectivityService;
+import com.android.server.connectivity.NetworkNotificationManager;
+import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
+
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LingerMonitorTest {
     static final String CELLULAR = "CELLULAR";
     static final String WIFI     = "WIFI";
 
@@ -62,6 +71,7 @@
     @Mock NetworkNotificationManager mNotifier;
     @Mock Resources mResources;
 
+    @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mCtx.getResources()).thenReturn(mResources);
@@ -71,7 +81,7 @@
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT);
     }
 
-    @SmallTest
+    @Test
     public void testTransitions() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         NetworkAgentInfo nai1 = wifiNai(100);
@@ -81,7 +91,7 @@
         assertFalse(mMonitor.isNotificationEnabled(nai2, nai1));
     }
 
-    @SmallTest
+    @Test
     public void testNotificationOnLinger() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -92,7 +102,7 @@
         verifyNotification(from, to);
     }
 
-    @SmallTest
+    @Test
     public void testToastOnLinger() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
@@ -103,7 +113,7 @@
         verifyToast(from, to);
     }
 
-    @SmallTest
+    @Test
     public void testNotificationClearedAfterDisconnect() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -117,7 +127,7 @@
         verify(mNotifier, times(1)).clearNotification(100);
     }
 
-    @SmallTest
+    @Test
     public void testNotificationClearedAfterSwitchingBack() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -131,7 +141,7 @@
         verify(mNotifier, times(1)).clearNotification(100);
     }
 
-    @SmallTest
+    @Test
     public void testUniqueToast() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
@@ -149,7 +159,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testMultipleNotifications() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -168,7 +178,7 @@
         verifyNotification(wifi2, cell);
     }
 
-    @SmallTest
+    @Test
     public void testRateLimiting() throws InterruptedException {
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT);
 
@@ -194,7 +204,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testDailyLimiting() throws InterruptedException {
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT);
 
@@ -221,7 +231,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testUniqueNotification() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -238,7 +248,7 @@
         verifyNotification(from, to);
     }
 
-    @SmallTest
+    @Test
     public void testIgnoreNeverValidatedNetworks() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -250,7 +260,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testIgnoreCurrentlyValidatedNetworks() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -262,7 +272,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testNoNotificationType() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch();
@@ -273,7 +283,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testNoTransitionToNotify() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NONE);
         setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -284,7 +294,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testDifferentTransitionToNotify() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch(transition(CELLULAR, WIFI));
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index 911347c..125fe72 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -34,20 +34,29 @@
 import android.content.res.Resources;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.SmallTest;
+
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import junit.framework.TestCase;
+
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-public class NetworkNotificationManagerTest extends TestCase {
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetworkNotificationManagerTest {
 
     static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities();
     static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities();
@@ -71,6 +80,7 @@
 
     NetworkNotificationManager mManager;
 
+    @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mCaptor = ArgumentCaptor.forClass(Notification.class);
@@ -87,7 +97,7 @@
         mManager = new NetworkNotificationManager(mCtx, mTelephonyManager, mNotificationManager);
     }
 
-    @SmallTest
+    @Test
     public void testNotificationsShownAndCleared() {
         final int NETWORK_ID_BASE = 100;
         List<NotificationType> types = Arrays.asList(NotificationType.values());
@@ -117,7 +127,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testNoInternetNotificationsNotShownForCellular() {
         mManager.showNotification(100, NO_INTERNET, mCellNai, mWifiNai, null, false);
         mManager.showNotification(101, LOST_INTERNET, mCellNai, mWifiNai, null, false);
@@ -131,7 +141,7 @@
         verify(mNotificationManager, times(1)).notifyAsUser(eq(tag), eq(eventId), any(), any());
     }
 
-    @SmallTest
+    @Test
     public void testNotificationsNotShownIfNoInternetCapability() {
         mWifiNai.networkCapabilities = new NetworkCapabilities();
         mWifiNai.networkCapabilities .addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
@@ -142,7 +152,7 @@
         verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
     }
 
-    @SmallTest
+    @Test
     public void testDuplicatedNotificationsNoInternetThenSignIn() {
         final int id = 101;
         final String tag = NetworkNotificationManager.tagFor(id);
@@ -164,7 +174,7 @@
         verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(SIGN_IN.eventId), any());
     }
 
-    @SmallTest
+    @Test
     public void testDuplicatedNotificationsSignInThenNoInternet() {
         final int id = 101;
         final String tag = NetworkNotificationManager.tagFor(id);
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 4f18da7..fe396c3 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -20,6 +20,9 @@
 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
 import static android.content.pm.UserInfo.FLAG_PRIMARY;
 import static android.content.pm.UserInfo.FLAG_RESTRICTED;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.AdditionalMatchers.*;
 import static org.mockito.Mockito.*;
 
@@ -42,14 +45,17 @@
 import android.os.Looper;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
 import com.android.internal.R;
 import com.android.internal.net.VpnConfig;
 
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
 import org.mockito.Answers;
 import org.mockito.InOrder;
 import org.mockito.Mock;
@@ -61,13 +67,16 @@
 import java.util.Map;
 import java.util.Set;
 
+
 /**
  * Tests for {@link Vpn}.
  *
  * Build, install and run with:
- *  runtest --path java/com/android/server/connectivity/VpnTest.java
+ *  runtest frameworks-net -c com.android.server.connectivity.VpnTest
  */
-public class VpnTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class VpnTest {
     private static final String TAG = "VpnTest";
 
     // Mock users
@@ -106,7 +115,7 @@
     @Mock private NotificationManager mNotificationManager;
     @Mock private Vpn.SystemServices mSystemServices;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
@@ -130,7 +139,7 @@
         doNothing().when(mNetService).registerObserver(any());
     }
 
-    @SmallTest
+    @Test
     public void testRestrictedProfilesAreAddedToVpn() {
         setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
 
@@ -144,7 +153,7 @@
         })), ranges);
     }
 
-    @SmallTest
+    @Test
     public void testManagedProfilesAreNotAddedToVpn() {
         setMockedUsers(primaryUser, managedProfileA);
 
@@ -157,7 +166,7 @@
         })), ranges);
     }
 
-    @SmallTest
+    @Test
     public void testAddUserToVpnOnlyAddsOneUser() {
         setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
 
@@ -170,7 +179,7 @@
         })), ranges);
     }
 
-    @SmallTest
+    @Test
     public void testUidWhiteAndBlacklist() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
         final UidRange user = UidRange.createForUser(primaryUser.id);
@@ -195,7 +204,7 @@
         })), disallow);
     }
 
-    @SmallTest
+    @Test
     public void testLockdownChangingPackage() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
         final UidRange user = UidRange.createForUser(primaryUser.id);
@@ -230,7 +239,7 @@
         assertUnblocked(vpn, user.start + PKG_UIDS[3]);
     }
 
-    @SmallTest
+    @Test
     public void testLockdownAddingAProfile() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
         setMockedUsers(primaryUser);
@@ -270,7 +279,7 @@
         }));
     }
 
-    @SmallTest
+    @Test
     public void testLockdownRuleRepeatability() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
 
@@ -293,7 +302,7 @@
         verify(mNetService, times(2)).setAllowOnlyVpnForUids(anyBoolean(), any(UidRange[].class));
     }
 
-    @SmallTest
+    @Test
     public void testLockdownRuleReversibility() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
 
@@ -322,7 +331,7 @@
         order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(entireUser));
     }
 
-    @SmallTest
+    @Test
     public void testIsAlwaysOnPackageSupported() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
 
@@ -356,7 +365,7 @@
         assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0]));
     }
 
-    @SmallTest
+    @Test
     public void testNotificationShownForAlwaysOnApp() {
         final UserHandle userHandle = UserHandle.of(primaryUser.id);
         final Vpn vpn = createVpn(primaryUser.id);
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index 9c10264..dbaf8e6 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -26,6 +26,9 @@
 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 org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
 
 import static com.android.server.net.NetworkStatsCollection.multiplySafe;
 
@@ -37,11 +40,12 @@
 import android.net.NetworkTemplate;
 import android.os.Process;
 import android.os.UserHandle;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.telephony.SubscriptionPlan;
 import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.text.format.DateUtils;
 import android.util.RecurrenceRule;
 
@@ -64,11 +68,17 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Tests for {@link NetworkStatsCollection}.
  */
+@RunWith(AndroidJUnit4.class)
 @SmallTest
-public class NetworkStatsCollectionTest extends AndroidTestCase {
+public class NetworkStatsCollectionTest {
 
     private static final String TEST_FILE = "test.bin";
     private static final String TEST_IMSI = "310260000000000";
@@ -79,18 +89,15 @@
 
     private static Clock sOriginalClock;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         sOriginalClock = RecurrenceRule.sClock;
-
         // ignore any device overlay while testing
         NetworkTemplate.forceAllNetworkTypes();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
+    @After
+    public void tearDown() throws Exception {
         RecurrenceRule.sClock = sOriginalClock;
     }
 
@@ -98,8 +105,10 @@
         RecurrenceRule.sClock = Clock.fixed(instant, ZoneId.systemDefault());
     }
 
+    @Test
     public void testReadLegacyNetwork() throws Exception {
-        final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
+        final File testFile =
+                new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE);
         stageFile(R.raw.netstats_v1, testFile);
 
         final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
@@ -124,8 +133,10 @@
                 636016770L, 709306L, 88038768L, 518836L, NetworkStatsAccess.Level.DEVICE);
     }
 
+    @Test
     public void testReadLegacyUid() throws Exception {
-        final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
+        final File testFile =
+                new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE);
         stageFile(R.raw.netstats_uid_v4, testFile);
 
         final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
@@ -150,8 +161,10 @@
                 637076152L, 711413L, 88343717L, 521022L, NetworkStatsAccess.Level.DEVICE);
     }
 
+    @Test
     public void testReadLegacyUidTags() throws Exception {
-        final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
+        final File testFile =
+                new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE);
         stageFile(R.raw.netstats_uid_v4, testFile);
 
         final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
@@ -176,6 +189,7 @@
                 77017831L, 100995L, 35436758L, 92344L);
     }
 
+    @Test
     public void testStartEndAtomicBuckets() throws Exception {
         final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS);
 
@@ -190,6 +204,7 @@
         assertEquals(2 * HOUR_IN_MILLIS, collection.getEndMillis());
     }
 
+    @Test
     public void testAccessLevels() throws Exception {
         final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS);
         final NetworkStats.Entry entry = new NetworkStats.Entry();
@@ -250,8 +265,10 @@
                 0, NetworkStatsAccess.Level.DEVICE);
     }
 
+    @Test
     public void testAugmentPlan() throws Exception {
-        final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
+        final File testFile =
+                new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE);
         stageFile(R.raw.netstats_v1, testFile);
 
         final NetworkStatsCollection emptyCollection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
@@ -439,6 +456,7 @@
         }
     }
 
+    @Test
     public void testAugmentPlanGigantic() throws Exception {
         // We're in the future, but not that far off
         setClock(Instant.parse("2012-06-01T00:00:00.00Z"));
@@ -461,6 +479,7 @@
         assertEquals(4_939_212_386L, getHistory(large, plan, TIME_A, TIME_C).getTotalBytes());
     }
 
+    @Test
     public void testRounding() throws Exception {
         final NetworkStatsCollection coll = new NetworkStatsCollection(HOUR_IN_MILLIS);
 
@@ -482,6 +501,7 @@
         assertEquals(TIME_A - HOUR_IN_MILLIS, coll.roundDown(TIME_A - 1));
     }
 
+    @Test
     public void testMultiplySafe() {
         assertEquals(25, multiplySafe(50, 1, 2));
         assertEquals(100, multiplySafe(50, 2, 1));
@@ -510,7 +530,7 @@
         InputStream in = null;
         OutputStream out = null;
         try {
-            in = getContext().getResources().openRawResource(rawId);
+            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
             out = new FileOutputStream(file);
             Streams.copy(in, out);
         } finally {
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 814a626..7f1bc5b 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -85,8 +85,8 @@
 import android.os.PowerManager;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 import android.util.TrustedTime;
 
@@ -201,7 +201,6 @@
               ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
         verify(mNetManager).registerObserver(networkObserver.capture());
         mNetworkObserver = networkObserver.getValue();
-
     }
 
     @After
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 4aeae70..9c4da1f 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -24,7 +24,6 @@
 import android.view.IWindowManager;
 import junit.framework.TestCase;
 
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 /**
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 5e85802..cb87737 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -739,12 +739,8 @@
 
     AssetManager assets;
     int32_t assetsCookie;
-    if (!assets.addAssetPath(String8(filename), &assetsCookie)) {
-        fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n");
-        return 1;
-    }
 
-    // Now add any dependencies passed in.
+    // Add any dependencies passed in.
     for (size_t i = 0; i < bundle->getPackageIncludes().size(); i++) {
       const String8& assetPath = bundle->getPackageIncludes()[i];
       if (!assets.addAssetPath(assetPath, NULL)) {
@@ -753,6 +749,11 @@
       }
     }
 
+    if (!assets.addAssetPath(String8(filename), &assetsCookie)) {
+        fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n");
+        return 1;
+    }
+
     // Make a dummy config for retrieving resources...  we need to supply
     // non-default values for some configs so that we can retrieve resources
     // in the app that don't have a default.  The most important of these is
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
index 041cb4f..8ebde75 100644
--- a/tools/aapt2/SdkConstants.cpp
+++ b/tools/aapt2/SdkConstants.cpp
@@ -25,8 +25,8 @@
 
 namespace aapt {
 
-static const char* sDevelopmentSdkCodeName = "O";
-static ApiVersion sDevelopmentSdkLevel = 26;
+static const char* sDevelopmentSdkCodeName = "P";
+static ApiVersion sDevelopmentSdkLevel = 28;
 
 static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = {
     {0x021c, 1},
@@ -53,6 +53,7 @@
     {0x0527, SDK_NOUGAT},
     {0x0530, SDK_NOUGAT_MR1},
     {0x0568, SDK_O},
+    {0x056d, SDK_O_MR1},
 };
 
 static bool less_entry_id(const std::pair<uint16_t, ApiVersion>& p, uint16_t entryId) {
@@ -70,680 +71,6 @@
   return iter->second;
 }
 
-static const std::unordered_map<std::string, ApiVersion> sAttrMap = {
-    {"marqueeRepeatLimit", 2},
-    {"windowNoDisplay", 3},
-    {"backgroundDimEnabled", 3},
-    {"inputType", 3},
-    {"isDefault", 3},
-    {"windowDisablePreview", 3},
-    {"privateImeOptions", 3},
-    {"editorExtras", 3},
-    {"settingsActivity", 3},
-    {"fastScrollEnabled", 3},
-    {"reqTouchScreen", 3},
-    {"reqKeyboardType", 3},
-    {"reqHardKeyboard", 3},
-    {"reqNavigation", 3},
-    {"windowSoftInputMode", 3},
-    {"imeFullscreenBackground", 3},
-    {"noHistory", 3},
-    {"headerDividersEnabled", 3},
-    {"footerDividersEnabled", 3},
-    {"candidatesTextStyleSpans", 3},
-    {"smoothScrollbar", 3},
-    {"reqFiveWayNav", 3},
-    {"keyBackground", 3},
-    {"keyTextSize", 3},
-    {"labelTextSize", 3},
-    {"keyTextColor", 3},
-    {"keyPreviewLayout", 3},
-    {"keyPreviewOffset", 3},
-    {"keyPreviewHeight", 3},
-    {"verticalCorrection", 3},
-    {"popupLayout", 3},
-    {"state_long_pressable", 3},
-    {"keyWidth", 3},
-    {"keyHeight", 3},
-    {"horizontalGap", 3},
-    {"verticalGap", 3},
-    {"rowEdgeFlags", 3},
-    {"codes", 3},
-    {"popupKeyboard", 3},
-    {"popupCharacters", 3},
-    {"keyEdgeFlags", 3},
-    {"isModifier", 3},
-    {"isSticky", 3},
-    {"isRepeatable", 3},
-    {"iconPreview", 3},
-    {"keyOutputText", 3},
-    {"keyLabel", 3},
-    {"keyIcon", 3},
-    {"keyboardMode", 3},
-    {"isScrollContainer", 3},
-    {"fillEnabled", 3},
-    {"updatePeriodMillis", 3},
-    {"initialLayout", 3},
-    {"voiceSearchMode", 3},
-    {"voiceLanguageModel", 3},
-    {"voicePromptText", 3},
-    {"voiceLanguage", 3},
-    {"voiceMaxResults", 3},
-    {"bottomOffset", 3},
-    {"topOffset", 3},
-    {"allowSingleTap", 3},
-    {"handle", 3},
-    {"content", 3},
-    {"animateOnClick", 3},
-    {"configure", 3},
-    {"hapticFeedbackEnabled", 3},
-    {"innerRadius", 3},
-    {"thickness", 3},
-    {"sharedUserLabel", 3},
-    {"dropDownWidth", 3},
-    {"dropDownAnchor", 3},
-    {"imeOptions", 3},
-    {"imeActionLabel", 3},
-    {"imeActionId", 3},
-    {"imeExtractEnterAnimation", 3},
-    {"imeExtractExitAnimation", 3},
-    {"tension", 4},
-    {"extraTension", 4},
-    {"anyDensity", 4},
-    {"searchSuggestThreshold", 4},
-    {"includeInGlobalSearch", 4},
-    {"onClick", 4},
-    {"targetSdkVersion", 4},
-    {"maxSdkVersion", 4},
-    {"testOnly", 4},
-    {"contentDescription", 4},
-    {"gestureStrokeWidth", 4},
-    {"gestureColor", 4},
-    {"uncertainGestureColor", 4},
-    {"fadeOffset", 4},
-    {"fadeDuration", 4},
-    {"gestureStrokeType", 4},
-    {"gestureStrokeLengthThreshold", 4},
-    {"gestureStrokeSquarenessThreshold", 4},
-    {"gestureStrokeAngleThreshold", 4},
-    {"eventsInterceptionEnabled", 4},
-    {"fadeEnabled", 4},
-    {"backupAgent", 4},
-    {"allowBackup", 4},
-    {"glEsVersion", 4},
-    {"queryAfterZeroResults", 4},
-    {"dropDownHeight", 4},
-    {"smallScreens", 4},
-    {"normalScreens", 4},
-    {"largeScreens", 4},
-    {"progressBarStyleInverse", 4},
-    {"progressBarStyleSmallInverse", 4},
-    {"progressBarStyleLargeInverse", 4},
-    {"searchSettingsDescription", 4},
-    {"textColorPrimaryInverseDisableOnly", 4},
-    {"autoUrlDetect", 4},
-    {"resizeable", 4},
-    {"required", 5},
-    {"accountType", 5},
-    {"contentAuthority", 5},
-    {"userVisible", 5},
-    {"windowShowWallpaper", 5},
-    {"wallpaperOpenEnterAnimation", 5},
-    {"wallpaperOpenExitAnimation", 5},
-    {"wallpaperCloseEnterAnimation", 5},
-    {"wallpaperCloseExitAnimation", 5},
-    {"wallpaperIntraOpenEnterAnimation", 5},
-    {"wallpaperIntraOpenExitAnimation", 5},
-    {"wallpaperIntraCloseEnterAnimation", 5},
-    {"wallpaperIntraCloseExitAnimation", 5},
-    {"supportsUploading", 5},
-    {"killAfterRestore", 5},
-    {"restoreNeedsApplication", 5},
-    {"smallIcon", 5},
-    {"accountPreferences", 5},
-    {"textAppearanceSearchResultSubtitle", 5},
-    {"textAppearanceSearchResultTitle", 5},
-    {"summaryColumn", 5},
-    {"detailColumn", 5},
-    {"detailSocialSummary", 5},
-    {"thumbnail", 5},
-    {"detachWallpaper", 5},
-    {"finishOnCloseSystemDialogs", 5},
-    {"scrollbarFadeDuration", 5},
-    {"scrollbarDefaultDelayBeforeFade", 5},
-    {"fadeScrollbars", 5},
-    {"colorBackgroundCacheHint", 5},
-    {"dropDownHorizontalOffset", 5},
-    {"dropDownVerticalOffset", 5},
-    {"quickContactBadgeStyleWindowSmall", 6},
-    {"quickContactBadgeStyleWindowMedium", 6},
-    {"quickContactBadgeStyleWindowLarge", 6},
-    {"quickContactBadgeStyleSmallWindowSmall", 6},
-    {"quickContactBadgeStyleSmallWindowMedium", 6},
-    {"quickContactBadgeStyleSmallWindowLarge", 6},
-    {"author", 7},
-    {"autoStart", 7},
-    {"expandableListViewWhiteStyle", 8},
-    {"installLocation", 8},
-    {"vmSafeMode", 8},
-    {"webTextViewStyle", 8},
-    {"restoreAnyVersion", 8},
-    {"tabStripLeft", 8},
-    {"tabStripRight", 8},
-    {"tabStripEnabled", 8},
-    {"logo", 9},
-    {"xlargeScreens", 9},
-    {"immersive", 9},
-    {"overScrollMode", 9},
-    {"overScrollHeader", 9},
-    {"overScrollFooter", 9},
-    {"filterTouchesWhenObscured", 9},
-    {"textSelectHandleLeft", 9},
-    {"textSelectHandleRight", 9},
-    {"textSelectHandle", 9},
-    {"textSelectHandleWindowStyle", 9},
-    {"popupAnimationStyle", 9},
-    {"screenSize", 9},
-    {"screenDensity", 9},
-    {"allContactsName", 11},
-    {"windowActionBar", 11},
-    {"actionBarStyle", 11},
-    {"navigationMode", 11},
-    {"displayOptions", 11},
-    {"subtitle", 11},
-    {"customNavigationLayout", 11},
-    {"hardwareAccelerated", 11},
-    {"measureWithLargestChild", 11},
-    {"animateFirstView", 11},
-    {"dropDownSpinnerStyle", 11},
-    {"actionDropDownStyle", 11},
-    {"actionButtonStyle", 11},
-    {"showAsAction", 11},
-    {"previewImage", 11},
-    {"actionModeBackground", 11},
-    {"actionModeCloseDrawable", 11},
-    {"windowActionModeOverlay", 11},
-    {"valueFrom", 11},
-    {"valueTo", 11},
-    {"valueType", 11},
-    {"propertyName", 11},
-    {"ordering", 11},
-    {"fragment", 11},
-    {"windowActionBarOverlay", 11},
-    {"fragmentOpenEnterAnimation", 11},
-    {"fragmentOpenExitAnimation", 11},
-    {"fragmentCloseEnterAnimation", 11},
-    {"fragmentCloseExitAnimation", 11},
-    {"fragmentFadeEnterAnimation", 11},
-    {"fragmentFadeExitAnimation", 11},
-    {"actionBarSize", 11},
-    {"imeSubtypeLocale", 11},
-    {"imeSubtypeMode", 11},
-    {"imeSubtypeExtraValue", 11},
-    {"splitMotionEvents", 11},
-    {"listChoiceBackgroundIndicator", 11},
-    {"spinnerMode", 11},
-    {"animateLayoutChanges", 11},
-    {"actionBarTabStyle", 11},
-    {"actionBarTabBarStyle", 11},
-    {"actionBarTabTextStyle", 11},
-    {"actionOverflowButtonStyle", 11},
-    {"actionModeCloseButtonStyle", 11},
-    {"titleTextStyle", 11},
-    {"subtitleTextStyle", 11},
-    {"iconifiedByDefault", 11},
-    {"actionLayout", 11},
-    {"actionViewClass", 11},
-    {"activatedBackgroundIndicator", 11},
-    {"state_activated", 11},
-    {"listPopupWindowStyle", 11},
-    {"popupMenuStyle", 11},
-    {"textAppearanceLargePopupMen", 11},
-    {"textAppearanceSmallPopupMen", 11},
-    {"breadCrumbTitle", 11},
-    {"breadCrumbShortTitle", 11},
-    {"listDividerAlertDialog", 11},
-    {"textColorAlertDialogListItem", 11},
-    {"loopViews", 11},
-    {"dialogTheme", 11},
-    {"alertDialogTheme", 11},
-    {"dividerVertical", 11},
-    {"homeAsUpIndicator", 11},
-    {"enterFadeDuration", 11},
-    {"exitFadeDuration", 11},
-    {"selectableItemBackground", 11},
-    {"autoAdvanceViewId", 11},
-    {"useIntrinsicSizeAsMinimum", 11},
-    {"actionModeCutDrawable", 11},
-    {"actionModeCopyDrawable", 11},
-    {"actionModePasteDrawable", 11},
-    {"textEditPasteWindowLayout", 11},
-    {"textEditNoPasteWindowLayout", 11},
-    {"textIsSelectable", 11},
-    {"windowEnableSplitTouch", 11},
-    {"indeterminateProgressStyle", 11},
-    {"progressBarPadding", 11},
-    {"animationResolution", 11},
-    {"state_accelerated", 11},
-    {"baseline", 11},
-    {"homeLayout", 11},
-    {"opacity", 11},
-    {"alpha", 11},
-    {"transformPivotX", 11},
-    {"transformPivotY", 11},
-    {"translationX", 11},
-    {"translationY", 11},
-    {"scaleX", 11},
-    {"scaleY", 11},
-    {"rotation", 11},
-    {"rotationX", 11},
-    {"rotationY", 11},
-    {"showDividers", 11},
-    {"dividerPadding", 11},
-    {"borderlessButtonStyle", 11},
-    {"dividerHorizontal", 11},
-    {"itemPadding", 11},
-    {"buttonBarStyle", 11},
-    {"buttonBarButtonStyle", 11},
-    {"segmentedButtonStyle", 11},
-    {"staticWallpaperPreview", 11},
-    {"allowParallelSyncs", 11},
-    {"isAlwaysSyncable", 11},
-    {"verticalScrollbarPosition", 11},
-    {"fastScrollAlwaysVisible", 11},
-    {"fastScrollThumbDrawable", 11},
-    {"fastScrollPreviewBackgroundLeft", 11},
-    {"fastScrollPreviewBackgroundRight", 11},
-    {"fastScrollTrackDrawable", 11},
-    {"fastScrollOverlayPosition", 11},
-    {"customTokens", 11},
-    {"nextFocusForward", 11},
-    {"firstDayOfWeek", 11},
-    {"showWeekNumber", 11},
-    {"minDate", 11},
-    {"maxDate", 11},
-    {"shownWeekCount", 11},
-    {"selectedWeekBackgroundColor", 11},
-    {"focusedMonthDateColor", 11},
-    {"unfocusedMonthDateColor", 11},
-    {"weekNumberColor", 11},
-    {"weekSeparatorLineColor", 11},
-    {"selectedDateVerticalBar", 11},
-    {"weekDayTextAppearance", 11},
-    {"dateTextAppearance", 11},
-    {"solidColor", 11},
-    {"spinnersShown", 11},
-    {"calendarViewShown", 11},
-    {"state_multiline", 11},
-    {"detailsElementBackground", 11},
-    {"textColorHighlightInverse", 11},
-    {"textColorLinkInverse", 11},
-    {"editTextColor", 11},
-    {"editTextBackground", 11},
-    {"horizontalScrollViewStyle", 11},
-    {"layerType", 11},
-    {"alertDialogIcon", 11},
-    {"windowMinWidthMajor", 11},
-    {"windowMinWidthMinor", 11},
-    {"queryHint", 11},
-    {"fastScrollTextColor", 11},
-    {"largeHeap", 11},
-    {"windowCloseOnTouchOutside", 11},
-    {"datePickerStyle", 11},
-    {"calendarViewStyle", 11},
-    {"textEditSidePasteWindowLayout", 11},
-    {"textEditSideNoPasteWindowLayout", 11},
-    {"actionMenuTextAppearance", 11},
-    {"actionMenuTextColor", 11},
-    {"textCursorDrawable", 12},
-    {"resizeMode", 12},
-    {"requiresSmallestWidthDp", 12},
-    {"compatibleWidthLimitDp", 12},
-    {"largestWidthLimitDp", 12},
-    {"state_hovered", 13},
-    {"state_drag_can_accept", 13},
-    {"state_drag_hovered", 13},
-    {"stopWithTask", 13},
-    {"switchTextOn", 13},
-    {"switchTextOff", 13},
-    {"switchPreferenceStyle", 13},
-    {"switchTextAppearance", 13},
-    {"track", 13},
-    {"switchMinWidth", 13},
-    {"switchPadding", 13},
-    {"thumbTextPadding", 13},
-    {"textSuggestionsWindowStyle", 13},
-    {"textEditSuggestionItemLayout", 13},
-    {"rowCount", 13},
-    {"rowOrderPreserved", 13},
-    {"columnCount", 13},
-    {"columnOrderPreserved", 13},
-    {"useDefaultMargins", 13},
-    {"alignmentMode", 13},
-    {"layout_row", 13},
-    {"layout_rowSpan", 13},
-    {"layout_columnSpan", 13},
-    {"actionModeSelectAllDrawable", 13},
-    {"isAuxiliary", 13},
-    {"accessibilityEventTypes", 13},
-    {"packageNames", 13},
-    {"accessibilityFeedbackType", 13},
-    {"notificationTimeout", 13},
-    {"accessibilityFlags", 13},
-    {"canRetrieveWindowContent", 13},
-    {"listPreferredItemHeightLarge", 13},
-    {"listPreferredItemHeightSmall", 13},
-    {"actionBarSplitStyle", 13},
-    {"actionProviderClass", 13},
-    {"backgroundStacked", 13},
-    {"backgroundSplit", 13},
-    {"textAllCaps", 13},
-    {"colorPressedHighlight", 13},
-    {"colorLongPressedHighlight", 13},
-    {"colorFocusedHighlight", 13},
-    {"colorActivatedHighlight", 13},
-    {"colorMultiSelectHighlight", 13},
-    {"drawableStart", 13},
-    {"drawableEnd", 13},
-    {"actionModeStyle", 13},
-    {"minResizeWidth", 13},
-    {"minResizeHeight", 13},
-    {"actionBarWidgetTheme", 13},
-    {"uiOptions", 13},
-    {"subtypeLocale", 13},
-    {"subtypeExtraValue", 13},
-    {"actionBarDivider", 13},
-    {"actionBarItemBackground", 13},
-    {"actionModeSplitBackground", 13},
-    {"textAppearanceListItem", 13},
-    {"textAppearanceListItemSmall", 13},
-    {"targetDescriptions", 13},
-    {"directionDescriptions", 13},
-    {"overridesImplicitlyEnabledSubtype", 13},
-    {"listPreferredItemPaddingLeft", 13},
-    {"listPreferredItemPaddingRight", 13},
-    {"requiresFadingEdge", 13},
-    {"publicKey", 13},
-    {"parentActivityName", 16},
-    {"isolatedProcess", 16},
-    {"importantForAccessibility", 16},
-    {"keyboardLayout", 16},
-    {"fontFamily", 16},
-    {"mediaRouteButtonStyle", 16},
-    {"mediaRouteTypes", 16},
-    {"supportsRtl", 17},
-    {"textDirection", 17},
-    {"textAlignment", 17},
-    {"layoutDirection", 17},
-    {"paddingStart", 17},
-    {"paddingEnd", 17},
-    {"layout_marginStart", 17},
-    {"layout_marginEnd", 17},
-    {"layout_toStartOf", 17},
-    {"layout_toEndOf", 17},
-    {"layout_alignStart", 17},
-    {"layout_alignEnd", 17},
-    {"layout_alignParentStart", 17},
-    {"layout_alignParentEnd", 17},
-    {"listPreferredItemPaddingStart", 17},
-    {"listPreferredItemPaddingEnd", 17},
-    {"singleUser", 17},
-    {"presentationTheme", 17},
-    {"subtypeId", 17},
-    {"initialKeyguardLayout", 17},
-    {"widgetCategory", 17},
-    {"permissionGroupFlags", 17},
-    {"labelFor", 17},
-    {"permissionFlags", 17},
-    {"checkedTextViewStyle", 17},
-    {"showOnLockScreen", 17},
-    {"format12Hour", 17},
-    {"format24Hour", 17},
-    {"timeZone", 17},
-    {"mipMap", 18},
-    {"mirrorForRtl", 18},
-    {"windowOverscan", 18},
-    {"requiredForAllUsers", 18},
-    {"indicatorStart", 18},
-    {"indicatorEnd", 18},
-    {"childIndicatorStart", 18},
-    {"childIndicatorEnd", 18},
-    {"restrictedAccountType", 18},
-    {"requiredAccountType", 18},
-    {"canRequestTouchExplorationMode", 18},
-    {"canRequestEnhancedWebAccessibility", 18},
-    {"canRequestFilterKeyEvents", 18},
-    {"layoutMode", 18},
-    {"keySet", 19},
-    {"targetId", 19},
-    {"fromScene", 19},
-    {"toScene", 19},
-    {"transition", 19},
-    {"transitionOrdering", 19},
-    {"fadingMode", 19},
-    {"startDelay", 19},
-    {"ssp", 19},
-    {"sspPrefix", 19},
-    {"sspPattern", 19},
-    {"addPrintersActivity", 19},
-    {"vendor", 19},
-    {"category", 19},
-    {"isAsciiCapable", 19},
-    {"autoMirrored", 19},
-    {"supportsSwitchingToNextInputMethod", 19},
-    {"requireDeviceUnlock", 19},
-    {"apduServiceBanner", 19},
-    {"accessibilityLiveRegion", 19},
-    {"windowTranslucentStatus", 19},
-    {"windowTranslucentNavigation", 19},
-    {"advancedPrintOptionsActivity", 19},
-    {"banner", 20},
-    {"windowSwipeToDismiss", 20},
-    {"isGame", 20},
-    {"allowEmbedded", 20},
-    {"setupActivity", 20},
-    {"fastScrollStyle", 21},
-    {"windowContentTransitions", 21},
-    {"windowContentTransitionManager", 21},
-    {"translationZ", 21},
-    {"tintMode", 21},
-    {"controlX1", 21},
-    {"controlY1", 21},
-    {"controlX2", 21},
-    {"controlY2", 21},
-    {"transitionName", 21},
-    {"transitionGroup", 21},
-    {"viewportWidth", 21},
-    {"viewportHeight", 21},
-    {"fillColor", 21},
-    {"pathData", 21},
-    {"strokeColor", 21},
-    {"strokeWidth", 21},
-    {"trimPathStart", 21},
-    {"trimPathEnd", 21},
-    {"trimPathOffset", 21},
-    {"strokeLineCap", 21},
-    {"strokeLineJoin", 21},
-    {"strokeMiterLimit", 21},
-    {"colorControlNormal", 21},
-    {"colorControlActivated", 21},
-    {"colorButtonNormal", 21},
-    {"colorControlHighlight", 21},
-    {"persistableMode", 21},
-    {"titleTextAppearance", 21},
-    {"subtitleTextAppearance", 21},
-    {"slideEdge", 21},
-    {"actionBarTheme", 21},
-    {"textAppearanceListItemSecondary", 21},
-    {"colorPrimary", 21},
-    {"colorPrimaryDark", 21},
-    {"colorAccent", 21},
-    {"nestedScrollingEnabled", 21},
-    {"windowEnterTransition", 21},
-    {"windowExitTransition", 21},
-    {"windowSharedElementEnterTransition", 21},
-    {"windowSharedElementExitTransition", 21},
-    {"windowAllowReturnTransitionOverlap", 21},
-    {"windowAllowEnterTransitionOverlap", 21},
-    {"sessionService", 21},
-    {"stackViewStyle", 21},
-    {"switchStyle", 21},
-    {"elevation", 21},
-    {"excludeId", 21},
-    {"excludeClass", 21},
-    {"hideOnContentScroll", 21},
-    {"actionOverflowMenuStyle", 21},
-    {"documentLaunchMode", 21},
-    {"maxRecents", 21},
-    {"autoRemoveFromRecents", 21},
-    {"stateListAnimator", 21},
-    {"toId", 21},
-    {"fromId", 21},
-    {"reversible", 21},
-    {"splitTrack", 21},
-    {"targetName", 21},
-    {"excludeName", 21},
-    {"matchOrder", 21},
-    {"windowDrawsSystemBarBackgrounds", 21},
-    {"statusBarColor", 21},
-    {"navigationBarColor", 21},
-    {"contentInsetStart", 21},
-    {"contentInsetEnd", 21},
-    {"contentInsetLeft", 21},
-    {"contentInsetRight", 21},
-    {"paddingMode", 21},
-    {"layout_rowWeight", 21},
-    {"layout_columnWeight", 21},
-    {"translateX", 21},
-    {"translateY", 21},
-    {"selectableItemBackgroundBorderless", 21},
-    {"elegantTextHeight", 21},
-    {"searchKeyphraseId", 21},
-    {"searchKeyphrase", 21},
-    {"searchKeyphraseSupportedLocales", 21},
-    {"windowTransitionBackgroundFadeDuration", 21},
-    {"overlapAnchor", 21},
-    {"progressTint", 21},
-    {"progressTintMode", 21},
-    {"progressBackgroundTint", 21},
-    {"progressBackgroundTintMode", 21},
-    {"secondaryProgressTint", 21},
-    {"secondaryProgressTintMode", 21},
-    {"indeterminateTint", 21},
-    {"indeterminateTintMode", 21},
-    {"backgroundTint", 21},
-    {"backgroundTintMode", 21},
-    {"foregroundTint", 21},
-    {"foregroundTintMode", 21},
-    {"buttonTint", 21},
-    {"buttonTintMode", 21},
-    {"thumbTint", 21},
-    {"thumbTintMode", 21},
-    {"fullBackupOnly", 21},
-    {"propertyXName", 21},
-    {"propertyYName", 21},
-    {"relinquishTaskIdentity", 21},
-    {"tileModeX", 21},
-    {"tileModeY", 21},
-    {"actionModeShareDrawable", 21},
-    {"actionModeFindDrawable", 21},
-    {"actionModeWebSearchDrawable", 21},
-    {"transitionVisibilityMode", 21},
-    {"minimumHorizontalAngle", 21},
-    {"minimumVerticalAngle", 21},
-    {"maximumAngle", 21},
-    {"searchViewStyle", 21},
-    {"closeIcon", 21},
-    {"goIcon", 21},
-    {"searchIcon", 21},
-    {"voiceIcon", 21},
-    {"commitIcon", 21},
-    {"suggestionRowLayout", 21},
-    {"queryBackground", 21},
-    {"submitBackground", 21},
-    {"buttonBarPositiveButtonStyle", 21},
-    {"buttonBarNeutralButtonStyle", 21},
-    {"buttonBarNegativeButtonStyle", 21},
-    {"popupElevation", 21},
-    {"actionBarPopupTheme", 21},
-    {"multiArch", 21},
-    {"touchscreenBlocksFocus", 21},
-    {"windowElevation", 21},
-    {"launchTaskBehindTargetAnimation", 21},
-    {"launchTaskBehindSourceAnimation", 21},
-    {"restrictionType", 21},
-    {"dayOfWeekBackground", 21},
-    {"dayOfWeekTextAppearance", 21},
-    {"headerMonthTextAppearance", 21},
-    {"headerDayOfMonthTextAppearance", 21},
-    {"headerYearTextAppearance", 21},
-    {"yearListItemTextAppearance", 21},
-    {"yearListSelectorColor", 21},
-    {"calendarTextColor", 21},
-    {"recognitionService", 21},
-    {"timePickerStyle", 21},
-    {"timePickerDialogTheme", 21},
-    {"headerTimeTextAppearance", 21},
-    {"headerAmPmTextAppearance", 21},
-    {"numbersTextColor", 21},
-    {"numbersBackgroundColor", 21},
-    {"numbersSelectorColor", 21},
-    {"amPmTextColor", 21},
-    {"amPmBackgroundColor", 21},
-    {"searchKeyphraseRecognitionFlags", 21},
-    {"checkMarkTint", 21},
-    {"checkMarkTintMode", 21},
-    {"popupTheme", 21},
-    {"toolbarStyle", 21},
-    {"windowClipToOutline", 21},
-    {"datePickerDialogTheme", 21},
-    {"showText", 21},
-    {"windowReturnTransition", 21},
-    {"windowReenterTransition", 21},
-    {"windowSharedElementReturnTransition", 21},
-    {"windowSharedElementReenterTransition", 21},
-    {"resumeWhilePausing", 21},
-    {"datePickerMode", 21},
-    {"timePickerMode", 21},
-    {"inset", 21},
-    {"letterSpacing", 21},
-    {"fontFeatureSettings", 21},
-    {"outlineProvider", 21},
-    {"contentAgeHint", 21},
-    {"country", 21},
-    {"windowSharedElementsUseOverlay", 21},
-    {"reparent", 21},
-    {"reparentWithOverlay", 21},
-    {"ambientShadowAlpha", 21},
-    {"spotShadowAlpha", 21},
-    {"navigationIcon", 21},
-    {"navigationContentDescription", 21},
-    {"fragmentExitTransition", 21},
-    {"fragmentEnterTransition", 21},
-    {"fragmentSharedElementEnterTransition", 21},
-    {"fragmentReturnTransition", 21},
-    {"fragmentSharedElementReturnTransition", 21},
-    {"fragmentReenterTransition", 21},
-    {"fragmentAllowEnterTransitionOverlap", 21},
-    {"fragmentAllowReturnTransitionOverlap", 21},
-    {"patternPathData", 21},
-    {"strokeAlpha", 21},
-    {"fillAlpha", 21},
-    {"windowActivityTransitions", 21},
-    {"colorEdgeEffect", 21}};
-
-ApiVersion FindAttributeSdkLevel(const ResourceName& name) {
-  if (name.package != "android" && name.type != ResourceType::kAttr) {
-    return 0;
-  }
-
-  auto iter = sAttrMap.find(name.entry);
-  if (iter != sAttrMap.end()) {
-    return iter->second;
-  }
-  return SDK_LOLLIPOP_MR1;
-}
-
 std::pair<StringPiece, ApiVersion> GetDevelopmentSdkCodeNameAndVersion() {
   return std::make_pair(StringPiece(sDevelopmentSdkCodeName), sDevelopmentSdkLevel);
 }
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
index 13584c0..5b7be3b 100644
--- a/tools/aapt2/SdkConstants.h
+++ b/tools/aapt2/SdkConstants.h
@@ -57,7 +57,6 @@
 };
 
 ApiVersion FindAttributeSdkLevel(const ResourceId& id);
-ApiVersion FindAttributeSdkLevel(const ResourceName& name);
 std::pair<android::StringPiece, ApiVersion> GetDevelopmentSdkCodeNameAndVersion();
 
 }  // namespace aapt
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 88e0f69..8cc2a61 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -254,10 +254,11 @@
 };
 
 static bool FlattenXml(IAaptContext* context, xml::XmlResource* xml_res, const StringPiece& path,
-                       bool keep_raw_values, IArchiveWriter* writer) {
+                       bool keep_raw_values, bool utf16, IArchiveWriter* writer) {
   BigBuffer buffer(1024);
   XmlFlattenerOptions options = {};
   options.keep_raw_values = keep_raw_values;
+  options.use_utf16 = utf16;
   XmlFlattener flattener(&buffer, options);
   if (!flattener.Consume(context, xml_res)) {
     return false;
@@ -607,7 +608,7 @@
               }
             }
             error |= !FlattenXml(context_, doc.get(), dst_path, options_.keep_raw_values,
-                                 archive_writer);
+                                 false /*utf16*/, archive_writer);
           }
         } else {
           error |= !io::CopyFileToArchive(context_, file_op.file_to_copy, file_op.dst_path,
@@ -1477,7 +1478,8 @@
   bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest,
                 ResourceTable* table) {
     const bool keep_raw_values = context_->GetPackageType() == PackageType::kStaticLib;
-    bool result = FlattenXml(context_, manifest, "AndroidManifest.xml", keep_raw_values, writer);
+    bool result = FlattenXml(context_, manifest, "AndroidManifest.xml", keep_raw_values,
+                             true /*utf16*/, writer);
     if (!result) {
       return false;
     }
diff --git a/tools/aapt2/format/binary/XmlFlattener.cpp b/tools/aapt2/format/binary/XmlFlattener.cpp
index f8f09ab..2456c3d 100644
--- a/tools/aapt2/format/binary/XmlFlattener.cpp
+++ b/tools/aapt2/format/binary/XmlFlattener.cpp
@@ -312,7 +312,11 @@
   xml_header_writer.StartChunk<ResXMLTree_header>(RES_XML_TYPE);
 
   // Flatten the StringPool.
-  StringPool::FlattenUtf8(buffer_, visitor.pool);
+  if (options_.use_utf16) {
+    StringPool::FlattenUtf16(buffer_, visitor.pool);
+  } else {
+    StringPool::FlattenUtf8(buffer_, visitor.pool);
+  }
 
   {
     // Write the array of resource IDs, indexed by StringPool order.
diff --git a/tools/aapt2/format/binary/XmlFlattener.h b/tools/aapt2/format/binary/XmlFlattener.h
index 6a48835..8db2281 100644
--- a/tools/aapt2/format/binary/XmlFlattener.h
+++ b/tools/aapt2/format/binary/XmlFlattener.h
@@ -28,6 +28,10 @@
 struct XmlFlattenerOptions {
   // Keep attribute raw string values along with typed values.
   bool keep_raw_values = false;
+
+  // Encode the strings in UTF-16. Only needed for AndroidManifest.xml to avoid a bug in
+  // certain non-AOSP platforms: https://issuetracker.google.com/64434571
+  bool use_utf16 = false;
 };
 
 class XmlFlattener : public IXmlResourceConsumer {
diff --git a/tools/incident_report/main.cpp b/tools/incident_report/main.cpp
index d4ad340..cc25264 100644
--- a/tools/incident_report/main.cpp
+++ b/tools/incident_report/main.cpp
@@ -97,8 +97,8 @@
                     message->addInt64(fieldId, value64);
                     break;
                 } else {
-                    fprintf(stderr, "bad VARINT: 0x%x (%d) at index %d\n", tag, tag,
-                                                    in->CurrentPosition());
+                    fprintf(stderr, "bad VARINT: 0x%x (%d) at index %d of field %s\n",
+                            tag, tag, in->CurrentPosition(), descriptor->name().c_str());
                     return false;
                 }
             case WireFormatLite::WIRETYPE_FIXED64:
@@ -106,14 +106,14 @@
                     message->addInt64(fieldId, value64);
                     break;
                 } else {
-                    fprintf(stderr, "bad VARINT: 0x%x (%d) at index %d\n", tag, tag,
-                            in->CurrentPosition());
+                    fprintf(stderr, "bad VARINT: 0x%x (%d) at index %d of field %s\n",
+                            tag, tag, in->CurrentPosition(), descriptor->name().c_str());
                     return false;
                 }
             case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
                 if (!read_length_delimited(in, fieldId, descriptor, message)) {
-                    fprintf(stderr, "bad LENGTH_DELIMITED: 0x%x (%d) at index %d\n",
-                            tag, tag, in->CurrentPosition());
+                    fprintf(stderr, "bad LENGTH_DELIMITED: 0x%x (%d) at index %d of field %s\n",
+                            tag, tag, in->CurrentPosition(), descriptor->name().c_str());
                     return false;
                 }
                 break;
@@ -122,13 +122,13 @@
                     message->addInt32(fieldId, value32);
                     break;
                 } else {
-                    fprintf(stderr, "bad FIXED32: 0x%x (%d) at index %d\n", tag, tag,
-                            in->CurrentPosition());
+                    fprintf(stderr, "bad FIXED32: 0x%x (%d) at index %d of field %s\n",
+                            tag, tag, in->CurrentPosition(), descriptor->name().c_str());
                     return false;
                 }
             default:
-                fprintf(stderr, "bad tag: 0x%x (%d) at index %d\n", tag, tag,
-                        in->CurrentPosition());
+                fprintf(stderr, "bad tag: 0x%x (%d) at index %d of field %s\n", tag, tag,
+                        in->CurrentPosition(), descriptor->name().c_str());
                 return false;
         }
     }
@@ -153,7 +153,8 @@
                     out->printf("%f", *(float*)&node.value32);
                     break;
                 default:
-                    out->printf("(unexpected value32 %d (0x%x)", node.value32, node.value32);
+                    out->printf("(unexpected type %d: value32 %d (0x%x)",
+                                type, node.value32, node.value32);
                     break;
             }
             break;
@@ -194,7 +195,8 @@
                     }
                     break;
                 default:
-                    out->printf("(unexpected value64 %lld (0x%x))", node.value64, node.value64);
+                    out->printf("(unexpected type %d: value64 %lld (0x%x))",
+                                type, node.value64, node.value64);
                     break;
             }
             break;
diff --git a/tools/locked_region_code_injection/Android.mk b/tools/locked_region_code_injection/Android.mk
index 77d5163..bb5f4d6 100644
--- a/tools/locked_region_code_injection/Android.mk
+++ b/tools/locked_region_code_injection/Android.mk
@@ -6,10 +6,10 @@
 LOCAL_MODULE := lockedregioncodeinjection
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    asm-5.2 \
-    asm-commons-5.2 \
-    asm-tree-5.2 \
-    asm-analysis-5.2 \
+    asm-6.0_BETA \
+    asm-commons-6.0_BETA \
+    asm-tree-6.0_BETA \
+    asm-analysis-6.0_BETA \
     guava-21.0 \
 
 include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java
index 99ef8a7..a60f2a2 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java
@@ -76,7 +76,7 @@
         private MethodVisitor chain;
 
         public LockFindingMethodVisitor(String owner, MethodNode mn, MethodVisitor chain) {
-            super(Opcodes.ASM5, mn);
+            super(Opcodes.ASM6, mn);
             assert owner != null;
             this.owner = owner;
             this.chain = chain;
diff --git a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java
index b86954d..c408b9e 100644
--- a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java
+++ b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java
@@ -23,11 +23,14 @@
  * <code>
  * set -x
  *
+ * croot frameworks/base/tools/locked_region_code_injection
+ *
  * # Clean
+ * mkdir -p out
  * rm -fr out/*
  *
  * # Make booster
- * javac -cp lib/asm-all-5.2.jar src&#47;*&#47;*.java -d out/
+ * javac -cp lib/asm-6.0_BETA.jar:lib/asm-commons-6.0_BETA.jar:lib/asm-tree-6.0_BETA.jar:lib/asm-analysis-6.0_BETA.jar:lib/guava-21.0.jar src&#47;*&#47;*.java -d out/
  * pushd out
  * jar cfe lockedregioncodeinjection.jar lockedregioncodeinjection.Main *&#47;*.class
  * popd
@@ -40,7 +43,7 @@
  * popd
  *
  * # Run tool on unit tests.
- * java -ea -cp lib/asm-all-5.2.jar:out/lockedregioncodeinjection.jar \
+ * java -ea -cp lib/asm-6.0_BETA.jar:lib/asm-commons-6.0_BETA.jar:lib/asm-tree-6.0_BETA.jar:lib/asm-analysis-6.0_BETA.jar:lib/guava-21.0.jar:out/lockedregioncodeinjection.jar \
  *     lockedregioncodeinjection.Main \
  *     -i out/test_input.jar -o out/test_output.jar \
  *     --targets 'Llockedregioncodeinjection/TestTarget;' \
diff --git a/tools/streaming_proto/Android.bp b/tools/streaming_proto/Android.bp
index 24068e9..756549c 100644
--- a/tools/streaming_proto/Android.bp
+++ b/tools/streaming_proto/Android.bp
@@ -17,13 +17,31 @@
 // ==========================================================
 // Build the host executable: protoc-gen-javastream
 // ==========================================================
-cc_binary_host {
-    name: "protoc-gen-javastream",
+cc_defaults {
+    name: "protoc-gen-stream-defaults",
     srcs: [
         "Errors.cpp",
         "string_utils.cpp",
-        "main.cpp",
+    ],
+}
+
+
+cc_binary_host {
+    name: "protoc-gen-javastream",
+    srcs: [
+        "java/main.cpp",
     ],
 
+    defaults: ["protoc-gen-stream-defaults"],
+    shared_libs: ["libprotoc"],
+}
+
+cc_binary_host {
+    name: "protoc-gen-cppstream",
+    srcs: [
+        "cpp/main.cpp",
+    ],
+
+    defaults: ["protoc-gen-stream-defaults"],
     shared_libs: ["libprotoc"],
 }
diff --git a/tools/streaming_proto/Errors.cpp b/tools/streaming_proto/Errors.cpp
index 91c6b92..0cd9037 100644
--- a/tools/streaming_proto/Errors.cpp
+++ b/tools/streaming_proto/Errors.cpp
@@ -3,7 +3,7 @@
 #include <stdlib.h>
 
 namespace android {
-namespace javastream_proto {
+namespace stream_proto {
 
 Errors ERRORS;
 
@@ -82,6 +82,6 @@
     return m_errors.size() > 0;
 }
 
-} // namespace javastream_proto
+} // namespace stream_proto
 } // namespace android
 
diff --git a/tools/streaming_proto/Errors.h b/tools/streaming_proto/Errors.h
index 109195a..f14bbfd 100644
--- a/tools/streaming_proto/Errors.h
+++ b/tools/streaming_proto/Errors.h
@@ -4,7 +4,7 @@
 #include <vector>
 
 namespace android {
-namespace javastream_proto {
+namespace stream_proto {
 
 using namespace std;
 
@@ -44,5 +44,5 @@
 extern const int UNKNOWN_LINE;
 
 
-} // namespace javastream_proto
+} // namespace stream_proto
 } // namespace android
diff --git a/tools/streaming_proto/cpp/main.cpp b/tools/streaming_proto/cpp/main.cpp
new file mode 100644
index 0000000..d4e1b7a
--- /dev/null
+++ b/tools/streaming_proto/cpp/main.cpp
@@ -0,0 +1,273 @@
+#include "Errors.h"
+#include "string_utils.h"
+
+#include "google/protobuf/compiler/plugin.pb.h"
+#include "google/protobuf/io/zero_copy_stream_impl.h"
+#include "google/protobuf/text_format.h"
+
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+using namespace android::stream_proto;
+using namespace google::protobuf;
+using namespace google::protobuf::compiler;
+using namespace google::protobuf::io;
+using namespace std;
+
+/**
+ * Position of the field type in a (long long) fieldId.
+ */
+const uint64_t FIELD_TYPE_SHIFT = 32;
+
+//
+// FieldId flags for whether the field is single, repeated or packed.
+// TODO: packed is not supported yet.
+//
+const uint64_t FIELD_COUNT_SHIFT = 40;
+const uint64_t FIELD_COUNT_MASK = 0x0fULL << FIELD_COUNT_SHIFT;
+const uint64_t FIELD_COUNT_UNKNOWN = 0;
+const uint64_t FIELD_COUNT_SINGLE = 1ULL << FIELD_COUNT_SHIFT;
+const uint64_t FIELD_COUNT_REPEATED = 2ULL << FIELD_COUNT_SHIFT;
+const uint64_t FIELD_COUNT_PACKED = 4ULL << FIELD_COUNT_SHIFT;
+
+// Indent
+const string INDENT = "    ";
+
+/**
+ * See if this is the file for this request, and not one of the imported ones.
+ */
+static bool
+should_generate_for_file(const CodeGeneratorRequest& request, const string& file)
+{
+    const int N = request.file_to_generate_size();
+    for (int i=0; i<N; i++) {
+        if (request.file_to_generate(i) == file) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static string
+make_filename(const FileDescriptorProto& file_descriptor)
+{
+    return file_descriptor.name() + ".h";
+}
+
+static string
+get_proto_type(const FieldDescriptorProto& field)
+{
+    switch (field.type()) {
+        case FieldDescriptorProto::TYPE_DOUBLE:
+            return "double";
+        case FieldDescriptorProto::TYPE_FLOAT:
+            return "float";
+        case FieldDescriptorProto::TYPE_INT64:
+            return "int64";
+        case FieldDescriptorProto::TYPE_UINT64:
+            return "uint64";
+        case FieldDescriptorProto::TYPE_INT32:
+            return "int32";
+        case FieldDescriptorProto::TYPE_FIXED64:
+            return "fixed64";
+        case FieldDescriptorProto::TYPE_FIXED32:
+            return "fixed32";
+        case FieldDescriptorProto::TYPE_BOOL:
+            return "bool";
+        case FieldDescriptorProto::TYPE_STRING:
+            return "string";
+        case FieldDescriptorProto::TYPE_GROUP:
+            return "group<unsupported!>";
+        case FieldDescriptorProto::TYPE_MESSAGE:
+            return field.type_name();
+        case FieldDescriptorProto::TYPE_BYTES:
+            return "bytes";
+        case FieldDescriptorProto::TYPE_UINT32:
+            return "uint32";
+        case FieldDescriptorProto::TYPE_ENUM:
+            return field.type_name();
+        case FieldDescriptorProto::TYPE_SFIXED32:
+            return "sfixed32";
+        case FieldDescriptorProto::TYPE_SFIXED64:
+            return "sfixed64";
+        case FieldDescriptorProto::TYPE_SINT32:
+            return "sint32";
+        case FieldDescriptorProto::TYPE_SINT64:
+            return "sint64";
+        default:
+            // won't happen
+            return "void";
+    }
+}
+
+static void
+write_enum(stringstream& text, const EnumDescriptorProto& enu, const string& indent)
+{
+    const int N = enu.value_size();
+    text << indent << "// enum " << enu.name() << endl;
+    for (int i=0; i<N; i++) {
+        const EnumValueDescriptorProto& value = enu.value(i);
+        text << indent << "const uint32_t "
+                << make_constant_name(value.name())
+                << " = " << value.number() << ";" << endl;
+    }
+    text << endl;
+}
+
+static uint64_t
+get_field_id(const FieldDescriptorProto& field)
+{
+    // Number
+    uint64_t result = (uint64_t)field.number();
+
+    // Type
+    result |= (uint64_t)field.type() << FIELD_TYPE_SHIFT;
+
+    // Count
+    if (field.options().packed()) {
+        result |= FIELD_COUNT_PACKED;
+    } else if (field.label() == FieldDescriptorProto::LABEL_REPEATED) {
+        result |= FIELD_COUNT_REPEATED;
+    } else {
+        result |= FIELD_COUNT_SINGLE;
+    }
+
+    return result;
+}
+
+static void
+write_field(stringstream& text, const FieldDescriptorProto& field, const string& indent)
+{
+    string optional_comment = field.label() == FieldDescriptorProto::LABEL_OPTIONAL
+            ? "optional " : "";
+    string repeated_comment = field.label() == FieldDescriptorProto::LABEL_REPEATED
+            ? "repeated " : "";
+    string proto_type = get_proto_type(field);
+    string packed_comment = field.options().packed()
+            ? " [packed=true]" : "";
+    text << indent << "// " << optional_comment << repeated_comment << proto_type << ' '
+            << field.name() << " = " << field.number() << packed_comment << ';' << endl;
+
+    text << indent << "const uint64_t " << make_constant_name(field.name()) << " = 0x";
+
+    ios::fmtflags fmt(text.flags());
+    text << setfill('0') << setw(16) << hex << get_field_id(field);
+    text.flags(fmt);
+
+    text << "LL;" << endl;
+
+    text << endl;
+}
+
+static void
+write_message(stringstream& text, const DescriptorProto& message, const string& indent)
+{
+    int N;
+    const string indented = indent + INDENT;
+
+    text << indent << "// message " << message.name() << endl;
+    text << indent << "class " << message.name() << " {" << endl;
+    text << indent << "public:" << endl;
+
+    // Enums
+    N = message.enum_type_size();
+    for (int i=0; i<N; i++) {
+        write_enum(text, message.enum_type(i), indented);
+    }
+
+    // Nested classes
+    N = message.nested_type_size();
+    for (int i=0; i<N; i++) {
+        write_message(text, message.nested_type(i), indented);
+    }
+
+    // Fields
+    N = message.field_size();
+    for (int i=0; i<N; i++) {
+        write_field(text, message.field(i), indented);
+    }
+
+    text << indent << "};" << endl;
+    text << endl;
+}
+
+static void
+write_cpp_file(CodeGeneratorResponse* response, const FileDescriptorProto& file_descriptor)
+{
+    stringstream text;
+
+    text << "// Generated by protoc-gen-cppstream. DO NOT MODIFY." << endl;
+    text << "// source: " << file_descriptor.name() << endl << endl;
+
+    string header = "ANDROID_" + replace_string(file_descriptor.name(), '/', '_');
+    header = replace_string(header, '.', '_') + "_stream_h";
+    header = make_constant_name(header);
+
+    text << "#ifndef " << header << endl;
+    text << "#define " << header << endl;
+    text << endl;
+
+    vector<string> namespaces = split(file_descriptor.package(), '.');
+    for (vector<string>::iterator it = namespaces.begin(); it != namespaces.end(); it++) {
+        text << "namespace " << *it << " {" << endl;
+    }
+    text << endl;
+
+    size_t N;
+    N = file_descriptor.enum_type_size();
+    for (size_t i=0; i<N; i++) {
+        write_enum(text, file_descriptor.enum_type(i), "");
+    }
+
+    N = file_descriptor.message_type_size();
+    for (size_t i=0; i<N; i++) {
+        write_message(text, file_descriptor.message_type(i), "");
+    }
+
+    for (vector<string>::iterator it = namespaces.begin(); it != namespaces.end(); it++) {
+        text << "} // " << *it << endl;
+    }
+
+    text << endl;
+    text << "#endif // " << header << endl;
+
+    CodeGeneratorResponse::File* file_response = response->add_file();
+    file_response->set_name(make_filename(file_descriptor));
+    file_response->set_content(text.str());
+}
+
+int main(int argc, char const *argv[])
+{
+    (void)argc;
+    (void)argv;
+
+    GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+    CodeGeneratorRequest request;
+    CodeGeneratorResponse response;
+
+    // Read the request
+    request.ParseFromIstream(&cin);
+
+    // Build the files we need.
+    const int N = request.proto_file_size();
+    for (int i=0; i<N; i++) {
+        const FileDescriptorProto& file_descriptor = request.proto_file(i);
+        if (should_generate_for_file(request, file_descriptor.name())) {
+            write_cpp_file(&response, file_descriptor);
+        }
+    }
+
+    // If we had errors, don't write the response. Print the errors and exit.
+    if (ERRORS.HasErrors()) {
+        ERRORS.Print();
+        return 1;
+    }
+
+    // If we didn't have errors, write the response and exit happily.
+    response.SerializeToOstream(&cout);
+
+    /* code */
+    return 0;
+}
\ No newline at end of file
diff --git a/tools/streaming_proto/main.cpp b/tools/streaming_proto/java/main.cpp
similarity index 99%
rename from tools/streaming_proto/main.cpp
rename to tools/streaming_proto/java/main.cpp
index 5b4ba04..b7d594b 100644
--- a/tools/streaming_proto/main.cpp
+++ b/tools/streaming_proto/java/main.cpp
@@ -12,7 +12,7 @@
 #include <sstream>
 #include <map>
 
-using namespace android::javastream_proto;
+using namespace android::stream_proto;
 using namespace google::protobuf;
 using namespace google::protobuf::compiler;
 using namespace google::protobuf::io;
diff --git a/tools/streaming_proto/string_utils.cpp b/tools/streaming_proto/string_utils.cpp
index cc738c4..bd34ab7 100644
--- a/tools/streaming_proto/string_utils.cpp
+++ b/tools/streaming_proto/string_utils.cpp
@@ -3,7 +3,7 @@
 #include <iostream>
 
 namespace android {
-namespace javastream_proto {
+namespace stream_proto {
 
 using namespace std;
 
@@ -89,7 +89,26 @@
     return result;
 }
 
-} // namespace javastream_proto
+vector<string>
+split(const string& str, const char delimiter)
+{
+    vector<string> result;
+    size_t base = 0, found = 0;
+    while (true) {
+        found = str.find_first_of(delimiter, base);
+        if (found != base) {
+            string part = str.substr(base, found - base);
+            if (!part.empty()) {
+                result.push_back(part);
+            }
+        }
+        if (found == str.npos) break;
+        base = found + 1;
+    }
+    return result;
+}
+
+} // namespace stream_proto
 } // namespace android
 
 
diff --git a/tools/streaming_proto/string_utils.h b/tools/streaming_proto/string_utils.h
index ffe83ca..03284d1 100644
--- a/tools/streaming_proto/string_utils.h
+++ b/tools/streaming_proto/string_utils.h
@@ -1,7 +1,8 @@
 #include <string>
+#include <vector>
 
 namespace android {
-namespace javastream_proto {
+namespace stream_proto {
 
 using namespace std;
 
@@ -26,7 +27,11 @@
  */
 string replace_string(const string& str, const char replace, const char with);
 
+/**
+ * Split a string to parts by delimiter.
+ */
+vector<string> split(const string& str, const char delimiter);
 
-} // namespace javastream_proto
+} // namespace stream_proto
 } // namespace android
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DebugFlagsChangedEvent.java b/wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl
similarity index 65%
rename from packages/SystemUI/src/com/android/systemui/recents/events/activity/DebugFlagsChangedEvent.java
rename to wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl
index fe3bf26..0e7289c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DebugFlagsChangedEvent.java
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -14,13 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
+package android.net.wifi.aware;
 
 /**
- * This is sent when the SystemUI tuner changes a flag.
+ * Callback for IWifiAwareManager.getMacAddressFromPeerHandle
+ *
+ * @hide
  */
-public class DebugFlagsChangedEvent extends EventBus.Event {
-    // Simple event
+oneway interface IWifiAwareMacAddressProvider
+{
+    void macAddress(in Map peerIdToMacMap);
 }
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
index f33424b..bad5ce2 100644
--- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
@@ -21,6 +21,7 @@
 import android.net.wifi.aware.ConfigRequest;
 import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
 import android.net.wifi.aware.IWifiAwareEventCallback;
+import android.net.wifi.aware.IWifiAwareMacAddressProvider;
 import android.net.wifi.aware.PublishConfig;
 import android.net.wifi.aware.SubscribeConfig;
 import android.net.wifi.aware.Characteristics;
@@ -52,4 +53,7 @@
     void sendMessage(int clientId, int discoverySessionId, int peerId, in byte[] message,
         int messageId, int retryCount);
     void terminateSession(int clientId, int discoverySessionId);
+
+    // internal APIs: intended to be used between System Services (restricted permissions)
+    void requestMacAddresses(int uid, in List peerIds, in IWifiAwareMacAddressProvider callback);
 }
diff --git a/wifi/java/android/net/wifi/aware/PeerHandle.java b/wifi/java/android/net/wifi/aware/PeerHandle.java
index cd45c52..1b0aba1 100644
--- a/wifi/java/android/net/wifi/aware/PeerHandle.java
+++ b/wifi/java/android/net/wifi/aware/PeerHandle.java
@@ -32,4 +32,24 @@
 
     /** @hide */
     public int peerId;
+
+    /** @hide RTT_API */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof PeerHandle)) {
+            return false;
+        }
+
+        return peerId == ((PeerHandle) o).peerId;
+    }
+
+    /** @hide RTT_API */
+    @Override
+    public int hashCode() {
+        return peerId;
+    }
 }