Merge "Ensure permissions granted for correct SIM" into qt-r1-dev
diff --git a/core/java/android/os/RedactingFileDescriptor.java b/core/java/android/os/RedactingFileDescriptor.java
index 4e5eaac..a1ed214 100644
--- a/core/java/android/os/RedactingFileDescriptor.java
+++ b/core/java/android/os/RedactingFileDescriptor.java
@@ -35,7 +35,7 @@
 
 /**
  * Variant of {@link FileDescriptor} that allows its creator to specify regions
- * that should be redacted (appearing as zeros to the reader).
+ * that should be redacted.
  *
  * @hide
  */
@@ -44,13 +44,16 @@
     private static final boolean DEBUG = true;
 
     private volatile long[] mRedactRanges;
+    private volatile long[] mFreeOffsets;
 
     private FileDescriptor mInner = null;
     private ParcelFileDescriptor mOuter = null;
 
-    private RedactingFileDescriptor(Context context, File file, int mode, long[] redactRanges)
+    private RedactingFileDescriptor(
+            Context context, File file, int mode, long[] redactRanges, long[] freeOffsets)
             throws IOException {
         mRedactRanges = checkRangesArgument(redactRanges);
+        mFreeOffsets = freeOffsets;
 
         try {
             try {
@@ -88,13 +91,17 @@
      *
      * @param file The underlying file to open.
      * @param mode The {@link ParcelFileDescriptor} mode to open with.
-     * @param redactRanges List of file offsets that should be redacted, stored
+     * @param redactRanges List of file ranges that should be redacted, stored
      *            as {@code [start1, end1, start2, end2, ...]}. Start values are
      *            inclusive and end values are exclusive.
+     * @param freePositions List of file offsets at which the four byte value 'free' should be
+     *            written instead of zeros within parts of the file covered by {@code redactRanges}.
+     *            Non-redacted bytes will not be modified even if covered by a 'free'. This is
+     *            useful for overwriting boxes in ISOBMFF files with padding data.
      */
     public static ParcelFileDescriptor open(Context context, File file, int mode,
-            long[] redactRanges) throws IOException {
-        return new RedactingFileDescriptor(context, file, mode, redactRanges).mOuter;
+            long[] redactRanges, long[] freePositions) throws IOException {
+        return new RedactingFileDescriptor(context, file, mode, redactRanges, freePositions).mOuter;
     }
 
     /**
@@ -169,6 +176,15 @@
                 for (long j = start; j < end; j++) {
                     data[(int) (j - offset)] = 0;
                 }
+                // Overwrite data at 'free' offsets within the redaction ranges.
+                for (long freeOffset : mFreeOffsets) {
+                    final long freeEnd = freeOffset + 4;
+                    final long redactFreeStart = Math.max(freeOffset, start);
+                    final long redactFreeEnd = Math.min(freeEnd, end);
+                    for (long j = redactFreeStart; j < redactFreeEnd; j++) {
+                        data[(int) (j - offset)] = (byte) "free".charAt((int) (j - freeOffset));
+                    }
+                }
             }
             return n;
         }
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 5778544..157e0a7 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -16,252 +16,167 @@
 
 package com.android.internal.app;
 
+import android.animation.ObjectAnimator;
 import android.animation.TimeAnimator;
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.ContentResolver;
 import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.ColorFilter;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.Shader;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.util.Log;
+import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
 import android.view.View;
-import android.widget.FrameLayout;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import com.android.internal.R;
 
 import org.json.JSONObject;
 
+/**
+ * @hide
+ */
 public class PlatLogoActivity extends Activity {
-    FrameLayout layout;
-    TimeAnimator anim;
-    PBackground bg;
+    ImageView mZeroView, mOneView;
+    BackslashDrawable mBackslash;
+    int mClicks;
 
-    private class PBackground extends Drawable {
-        private float maxRadius, radius, x, y, dp;
-        private int[] palette;
-        private int darkest;
-        private float offset;
+    static final Paint sPaint = new Paint();
+    static {
+        sPaint.setStyle(Paint.Style.STROKE);
+        sPaint.setStrokeWidth(4f);
+        sPaint.setStrokeCap(Paint.Cap.SQUARE);
+    }
 
-        public PBackground() {
-            randomizePalette();
+    @Override
+    protected void onPause() {
+        if (mBackslash != null) {
+            mBackslash.stopAnimating();
         }
-
-        /**
-         * set inner radius of "p" logo
-         */
-        public void setRadius(float r) {
-            this.radius = Math.max(48*dp, r);
-        }
-
-        /**
-         * move the "p"
-         */
-        public void setPosition(float x, float y) {
-            this.x = x;
-            this.y = y;
-        }
-
-        /**
-         * for animating the "p"
-         */
-        public void setOffset(float o) {
-            this.offset = o;
-        }
-
-        /**
-         * rough luminance calculation
-         * https://www.w3.org/TR/AERT/#color-contrast
-         */
-        public float lum(int rgb) {
-            return ((Color.red(rgb) * 299f) + (Color.green(rgb) * 587f) + (Color.blue(rgb) * 114f)) / 1000f;
-        }
-
-        /**
-         * create a random evenly-spaced color palette
-         * guaranteed to contrast!
-         */
-        public void randomizePalette() {
-            final int slots = 2 + (int)(Math.random() * 2);
-            float[] color = new float[] { (float) Math.random() * 360f, 1f, 1f };
-            palette = new int[slots];
-            darkest = 0;
-            for (int i=0; i<slots; i++) {
-                palette[i] = Color.HSVToColor(color);
-                color[0] = (color[0] + 360f/slots) % 360f;
-                if (lum(palette[i]) < lum(palette[darkest])) darkest = i;
-            }
-
-            final StringBuilder str = new StringBuilder();
-            for (int c : palette) {
-                str.append(String.format("#%08x ", c));
-            }
-            Log.v("PlatLogoActivity", "color palette: " + str);
-        }
-
-        @Override
-        public void draw(Canvas canvas) {
-            if (dp == 0) dp = getResources().getDisplayMetrics().density;
-            final float width = canvas.getWidth();
-            final float height = canvas.getHeight();
-            if (radius == 0) {
-                setPosition(width / 2, height / 2);
-                setRadius(width / 6);
-            }
-            final float inner_w = radius * 0.667f;
-
-            final Paint paint = new Paint();
-            paint.setStrokeCap(Paint.Cap.BUTT);
-            canvas.translate(x, y);
-
-            Path p = new Path();
-            p.moveTo(-radius, height);
-            p.lineTo(-radius, 0);
-            p.arcTo(-radius, -radius, radius, radius, -180, 270, false);
-            p.lineTo(-radius, radius);
-
-            float w = Math.max(canvas.getWidth(), canvas.getHeight())  * 1.414f;
-            paint.setStyle(Paint.Style.FILL);
-
-            int i=0;
-            while (w > radius*2 + inner_w*2) {
-                paint.setColor(0xFF000000 | palette[i % palette.length]);
-                // for a slower but more complete version:
-                // paint.setStrokeWidth(w);
-                // canvas.drawPath(p, paint);
-                canvas.drawOval(-w/2, -w/2, w/2, w/2, paint);
-                w -= inner_w * (1.1f + Math.sin((i/20f + offset) * 3.14159f));
-                i++;
-            }
-
-            // the innermost circle needs to be a constant color to avoid rapid flashing
-            paint.setColor(0xFF000000 | palette[(darkest+1) % palette.length]);
-            canvas.drawOval(-radius, -radius, radius, radius, paint);
-
-            p.reset();
-            p.moveTo(-radius, height);
-            p.lineTo(-radius, 0);
-            p.arcTo(-radius, -radius, radius, radius, -180, 270, false);
-            p.lineTo(-radius + inner_w, radius);
-
-            paint.setStyle(Paint.Style.STROKE);
-            paint.setStrokeWidth(inner_w*2);
-            paint.setColor(palette[darkest]);
-            canvas.drawPath(p, paint);
-            paint.setStrokeWidth(inner_w);
-            paint.setColor(0xFFFFFFFF);
-            canvas.drawPath(p, paint);
-        }
-
-        @Override
-        public void setAlpha(int alpha) {
-
-        }
-
-        @Override
-        public void setColorFilter(ColorFilter colorFilter) {
-
-        }
-
-        @Override
-        public int getOpacity() {
-            return 0;
-        }
+        mClicks = 0;
+        super.onPause();
     }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        final float dp = getResources().getDisplayMetrics().density;
 
-        layout = new FrameLayout(this);
-        setContentView(layout);
+        getWindow().getDecorView().setSystemUiVisibility(
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+        getWindow().setNavigationBarColor(0);
+        getWindow().setStatusBarColor(0);
 
-        bg = new PBackground();
-        layout.setBackground(bg);
+        getActionBar().hide();
 
-        final ContentResolver cr = getContentResolver();
+        setContentView(R.layout.platlogo_layout);
 
-        layout.setOnTouchListener(new View.OnTouchListener() {
-            final String TOUCH_STATS = "touch.stats";
+        mBackslash = new BackslashDrawable((int) (50 * dp));
 
-            final PointerCoords pc0 = new PointerCoords();
-            final PointerCoords pc1 = new PointerCoords();
+        mOneView = findViewById(R.id.one);
+        mOneView.setImageDrawable(new OneDrawable());
+        mZeroView = findViewById(R.id.zero);
+        mZeroView.setImageDrawable(new ZeroDrawable());
 
-            double pressure_min, pressure_max;
-            int maxPointers;
-            int tapCount;
+        final ViewGroup root = (ViewGroup) mOneView.getParent();
+        root.setClipChildren(false);
+        root.setBackground(mBackslash);
+        root.getBackground().setAlpha(0x20);
 
+        View.OnTouchListener tl = new View.OnTouchListener() {
+            float mOffsetX, mOffsetY;
+            long mClickTime;
+            ObjectAnimator mRotAnim;
             @Override
             public boolean onTouch(View v, MotionEvent event) {
-                final float pressure = event.getPressure();
+                measureTouchPressure(event);
                 switch (event.getActionMasked()) {
                     case MotionEvent.ACTION_DOWN:
-                        pressure_min = pressure_max = pressure;
-                        // fall through
-                    case MotionEvent.ACTION_MOVE:
-                        if (pressure < pressure_min) pressure_min = pressure;
-                        if (pressure > pressure_max) pressure_max = pressure;
-                        final int pc = event.getPointerCount();
-                        if (pc > maxPointers) maxPointers = pc;
-                        if (pc > 1) {
-                            event.getPointerCoords(0, pc0);
-                            event.getPointerCoords(1, pc1);
-                            bg.setRadius((float) Math.hypot(pc0.x - pc1.x, pc0.y - pc1.y) / 2f);
+                        v.animate().scaleX(1.1f).scaleY(1.1f);
+                        v.getParent().bringChildToFront(v);
+                        mOffsetX = event.getRawX() - v.getX();
+                        mOffsetY = event.getRawY() - v.getY();
+                        long now = System.currentTimeMillis();
+                        if (now - mClickTime < 350) {
+                            mRotAnim = ObjectAnimator.ofFloat(v, View.ROTATION,
+                                    v.getRotation(), v.getRotation() + 3600);
+                            mRotAnim.setDuration(10000);
+                            mRotAnim.start();
+                            mClickTime = 0;
+                        } else {
+                            mClickTime = now;
                         }
                         break;
-                    case MotionEvent.ACTION_CANCEL:
+                    case MotionEvent.ACTION_MOVE:
+                        v.setX(event.getRawX() - mOffsetX);
+                        v.setY(event.getRawY() - mOffsetY);
+                        v.performHapticFeedback(HapticFeedbackConstants.TEXT_HANDLE_MOVE);
+                        break;
                     case MotionEvent.ACTION_UP:
-                        try {
-                            final String touchDataJson = Settings.System.getString(cr, TOUCH_STATS);
-                            final JSONObject touchData = new JSONObject(
-                                    touchDataJson != null ? touchDataJson : "{}");
-                            if (touchData.has("min")) {
-                                pressure_min = Math.min(pressure_min, touchData.getDouble("min"));
-                            }
-                            if (touchData.has("max")) {
-                                pressure_max = Math.max(pressure_max, touchData.getDouble("max"));
-                            }
-                            touchData.put("min", pressure_min);
-                            touchData.put("max", pressure_max);
-                            Settings.System.putString(cr, TOUCH_STATS, touchData.toString());
-                        } catch (Exception e) {
-                            Log.e("PlatLogoActivity", "Can't write touch settings", e);
-                        }
-
-                        if (maxPointers == 1) {
-                            tapCount ++;
-                            if (tapCount < 7) {
-                                bg.randomizePalette();
-                            } else {
-                                launchNextStage();
-                            }
-                        } else {
-                            tapCount = 0;
-                        }
-                        maxPointers = 0;
+                        v.performClick();
+                        // fall through
+                    case MotionEvent.ACTION_CANCEL:
+                        v.animate().scaleX(1f).scaleY(1f);
+                        if (mRotAnim != null) mRotAnim.cancel();
+                        testOverlap();
                         break;
                 }
                 return true;
             }
-        });
+        };
+
+        findViewById(R.id.one).setOnTouchListener(tl);
+        findViewById(R.id.zero).setOnTouchListener(tl);
+        findViewById(R.id.text).setOnTouchListener(tl);
+    }
+
+    private void testOverlap() {
+        final float width = mZeroView.getWidth();
+        final float targetX = mZeroView.getX() + width * .2f;
+        final float targetY = mZeroView.getY() + width * .3f;
+        if (Math.hypot(targetX - mOneView.getX(), targetY - mOneView.getY()) < width * .2f
+                && Math.abs(mOneView.getRotation() % 360 - 315) < 15) {
+            mOneView.animate().x(mZeroView.getX() + width * .2f);
+            mOneView.animate().y(mZeroView.getY() + width * .3f);
+            mOneView.setRotation(mOneView.getRotation() % 360);
+            mOneView.animate().rotation(315);
+            mOneView.performHapticFeedback(HapticFeedbackConstants.CONFIRM);
+
+            mBackslash.startAnimating();
+
+            mClicks++;
+            if (mClicks >= 7) {
+                launchNextStage();
+            }
+        } else {
+            mBackslash.stopAnimating();
+        }
     }
 
     private void launchNextStage() {
         final ContentResolver cr = getContentResolver();
 
-        if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0) == 0) {
+        if (Settings.System.getLong(cr, "egg_mode" /* Settings.System.EGG_MODE */, 0) == 0) {
             // For posterity: the moment this user unlocked the easter egg
             try {
                 Settings.System.putLong(cr,
-                        Settings.System.EGG_MODE,
+                        "egg_mode", // Settings.System.EGG_MODE,
                         System.currentTimeMillis());
             } catch (RuntimeException e) {
-                Log.e("PlatLogoActivity", "Can't write settings", e);
+                Log.e("com.android.internal.app.PlatLogoActivity", "Can't write settings", e);
             }
         }
         try {
@@ -270,36 +185,206 @@
                         | Intent.FLAG_ACTIVITY_CLEAR_TASK)
                     .addCategory("com.android.internal.category.PLATLOGO"));
         } catch (ActivityNotFoundException ex) {
-            Log.e("PlatLogoActivity", "No more eggs.");
+            Log.e("com.android.internal.app.PlatLogoActivity", "No more eggs.");
         }
         finish();
     }
 
+    static final String TOUCH_STATS = "touch.stats";
+    double mPressureMin = 0, mPressureMax = -1;
+
+    private void measureTouchPressure(MotionEvent event) {
+        final float pressure = event.getPressure();
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                if (mPressureMax < 0) {
+                    mPressureMin = mPressureMax = pressure;
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (pressure < mPressureMin) mPressureMin = pressure;
+                if (pressure > mPressureMax) mPressureMax = pressure;
+                break;
+        }
+    }
+
+    private void syncTouchPressure() {
+        try {
+            final String touchDataJson = Settings.System.getString(
+                    getContentResolver(), TOUCH_STATS);
+            final JSONObject touchData = new JSONObject(
+                    touchDataJson != null ? touchDataJson : "{}");
+            if (touchData.has("min")) {
+                mPressureMin = Math.min(mPressureMin, touchData.getDouble("min"));
+            }
+            if (touchData.has("max")) {
+                mPressureMax = Math.max(mPressureMax, touchData.getDouble("max"));
+            }
+            if (mPressureMax >= 0) {
+                touchData.put("min", mPressureMin);
+                touchData.put("max", mPressureMax);
+                Settings.System.putString(getContentResolver(), TOUCH_STATS, touchData.toString());
+            }
+        } catch (Exception e) {
+            Log.e("com.android.internal.app.PlatLogoActivity", "Can't write touch settings", e);
+        }
+    }
+
     @Override
     public void onStart() {
         super.onStart();
-
-        bg.randomizePalette();
-
-        anim = new TimeAnimator();
-        anim.setTimeListener(
-                new TimeAnimator.TimeListener() {
-                    @Override
-                    public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
-                        bg.setOffset((float) totalTime / 60000f);
-                        bg.invalidateSelf();
-                    }
-                });
-
-        anim.start();
+        syncTouchPressure();
     }
 
     @Override
     public void onStop() {
-        if (anim != null) {
-            anim.cancel();
-            anim = null;
-        }
+        syncTouchPressure();
         super.onStop();
     }
+
+    static class ZeroDrawable extends Drawable {
+        int mTintColor;
+
+        @Override
+        public void draw(Canvas canvas) {
+            sPaint.setColor(mTintColor | 0xFF000000);
+
+            canvas.save();
+            canvas.scale(canvas.getWidth() / 24f, canvas.getHeight() / 24f);
+
+            canvas.drawCircle(12f, 12f, 10f, sPaint);
+            canvas.restore();
+        }
+
+        @Override
+        public void setAlpha(int alpha) { }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) { }
+
+        @Override
+        public void setTintList(ColorStateList tint) {
+            mTintColor = tint.getDefaultColor();
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+    }
+
+    static class OneDrawable extends Drawable {
+        int mTintColor;
+
+        @Override
+        public void draw(Canvas canvas) {
+            sPaint.setColor(mTintColor | 0xFF000000);
+
+            canvas.save();
+            canvas.scale(canvas.getWidth() / 24f, canvas.getHeight() / 24f);
+
+            final Path p = new Path();
+            p.moveTo(12f, 21.83f);
+            p.rLineTo(0f, -19.67f);
+            p.rLineTo(-5f, 0f);
+            canvas.drawPath(p, sPaint);
+            canvas.restore();
+        }
+
+        @Override
+        public void setAlpha(int alpha) { }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) { }
+
+        @Override
+        public void setTintList(ColorStateList tint) {
+            mTintColor = tint.getDefaultColor();
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+    }
+
+    private static class BackslashDrawable extends Drawable implements TimeAnimator.TimeListener {
+        Bitmap mTile;
+        Paint mPaint = new Paint();
+        BitmapShader mShader;
+        TimeAnimator mAnimator = new TimeAnimator();
+        Matrix mMatrix = new Matrix();
+
+        public void draw(Canvas canvas) {
+            canvas.drawPaint(mPaint);
+        }
+
+        BackslashDrawable(int width) {
+            mTile = Bitmap.createBitmap(width, width, Bitmap.Config.ALPHA_8);
+            mAnimator.setTimeListener(this);
+
+            final Canvas tileCanvas = new Canvas(mTile);
+            final float w = tileCanvas.getWidth();
+            final float h = tileCanvas.getHeight();
+
+            final Path path = new Path();
+            path.moveTo(0, 0);
+            path.lineTo(w / 2, 0);
+            path.lineTo(w, h / 2);
+            path.lineTo(w, h);
+            path.close();
+
+            path.moveTo(0, h / 2);
+            path.lineTo(w / 2, h);
+            path.lineTo(0, h);
+            path.close();
+
+            final Paint slashPaint = new Paint();
+            slashPaint.setAntiAlias(true);
+            slashPaint.setStyle(Paint.Style.FILL);
+            slashPaint.setColor(0xFF000000);
+            tileCanvas.drawPath(path, slashPaint);
+
+            //mPaint.setColor(0xFF0000FF);
+            mShader = new BitmapShader(mTile, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
+            mPaint.setShader(mShader);
+        }
+
+        public void startAnimating() {
+            if (!mAnimator.isStarted()) {
+                mAnimator.start();
+            }
+        }
+
+        public void stopAnimating() {
+            if (mAnimator.isStarted()) {
+                mAnimator.cancel();
+            }
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+            mPaint.setAlpha(alpha);
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) {
+            mPaint.setColorFilter(colorFilter);
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+
+        @Override
+        public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
+            if (mShader != null) {
+                mMatrix.postTranslate(deltaTime / 4f, 0);
+                mShader.setLocalMatrix(mMatrix);
+                invalidateSelf();
+            }
+        }
+    }
 }
+
diff --git a/core/java/com/android/internal/policy/ScreenDecorationsUtils.java b/core/java/com/android/internal/policy/ScreenDecorationsUtils.java
index adf7692..52172cf 100644
--- a/core/java/com/android/internal/policy/ScreenDecorationsUtils.java
+++ b/core/java/com/android/internal/policy/ScreenDecorationsUtils.java
@@ -36,13 +36,16 @@
         }
 
         // Radius that should be used in case top or bottom aren't defined.
-        float defaultRadius = resources.getDimension(R.dimen.rounded_corner_radius);
+        float defaultRadius = resources.getDimension(R.dimen.rounded_corner_radius)
+                - resources.getDimension(R.dimen.rounded_corner_radius_adjustment);
 
-        float topRadius = resources.getDimension(R.dimen.rounded_corner_radius_top);
+        float topRadius = resources.getDimension(R.dimen.rounded_corner_radius_top)
+                - resources.getDimension(R.dimen.rounded_corner_radius_top_adjustment);
         if (topRadius == 0f) {
             topRadius = defaultRadius;
         }
-        float bottomRadius = resources.getDimension(R.dimen.rounded_corner_radius_bottom);
+        float bottomRadius = resources.getDimension(R.dimen.rounded_corner_radius_bottom)
+                - resources.getDimension(R.dimen.rounded_corner_radius_bottom_adjustment);
         if (bottomRadius == 0f) {
             bottomRadius = defaultRadius;
         }
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 14dbabb..c3e7a36 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -575,7 +575,7 @@
     if (outArray != NULL) {
         outLen = MEMINFO_COUNT;
         for (int i = 0; i < outLen; i++) {
-            if (i == MEMINFO_VMALLOC_USED) {
+            if (i == MEMINFO_VMALLOC_USED && mem[i] == 0) {
                 outArray[i] = smi.ReadVmallocInfo() / 1024;
                 continue;
             }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index fef4dcd..eda6cd0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -724,6 +724,10 @@
 
     <!-- Allows an application to send SMS messages.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.SEND_SMS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -734,6 +738,10 @@
 
     <!-- Allows an application to receive SMS messages.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.RECEIVE_SMS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -744,6 +752,10 @@
 
     <!-- Allows an application to read SMS messages.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.READ_SMS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -754,6 +766,10 @@
 
     <!-- Allows an application to receive WAP push messages.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.RECEIVE_WAP_PUSH"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -763,7 +779,11 @@
         android:protectionLevel="dangerous" />
 
     <!-- Allows an application to monitor incoming MMS messages.
-        <p>Protection level: dangerous
+         <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.RECEIVE_MMS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -783,6 +803,11 @@
          when the alert is first received, and to delay presenting the info
          to the user until after the initial alert dialog is dismissed.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
+
          @hide Pending API council approval -->
     <permission android:name="android.permission.READ_CELL_BROADCASTS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -805,30 +830,35 @@
         android:priority="900" />
 
     <!-- Allows an application to read from external storage.
-     <p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly
-     granted this permission.</p>
-     <p>This permission is enforced starting in API level 19.  Before API level 19, this
-     permission is not enforced and all apps still have access to read from external storage.
-     You can test your app with the permission enforced by enabling <em>Protect USB
-     storage</em> under Developer options in the Settings app on a device running Android 4.1 or
-     higher.</p>
-     <p>Also starting in API level 19, this permission is <em>not</em> required to
-     read/write files in your application-specific directories returned by
-     {@link android.content.Context#getExternalFilesDir} and
-     {@link android.content.Context#getExternalCacheDir}.
-     <p class="note"><strong>Note:</strong> If <em>both</em> your <a
-     href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
-     minSdkVersion}</a> and <a
-     href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-     targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
-     grants your app this permission. If you don't need this permission, be sure your <a
-     href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-     targetSdkVersion}</a> is 4 or higher.
-     <p>Is this permission is not whitelisted for an app that targets an API level before
-     {@link android.os.Build.VERSION_CODES#Q} this permission cannot be granted to apps.</p>
-     <p>Is this permission is not whitelisted for an app that targets an API level
-     {@link android.os.Build.VERSION_CODES#Q} or later the app will be forced into isolated storage.
-     </p>
+      <p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly
+      granted this permission.</p>
+      <p>This permission is enforced starting in API level 19.  Before API level 19, this
+      permission is not enforced and all apps still have access to read from external storage.
+      You can test your app with the permission enforced by enabling <em>Protect USB
+      storage</em> under Developer options in the Settings app on a device running Android 4.1 or
+      higher.</p>
+      <p>Also starting in API level 19, this permission is <em>not</em> required to
+      read/write files in your application-specific directories returned by
+      {@link android.content.Context#getExternalFilesDir} and
+      {@link android.content.Context#getExternalCacheDir}.
+      <p class="note"><strong>Note:</strong> If <em>both</em> your <a
+      href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+      minSdkVersion}</a> and <a
+      href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+      targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
+      grants your app this permission. If you don't need this permission, be sure your <a
+      href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+      targetSdkVersion}</a> is 4 or higher.
+
+      <p> This is a soft restricted permission which cannot be held by an app it its
+      full form until the installer on record did not whitelist the permission.
+      Specifically, if the permission is whitelisted the holder app can access
+      external storage and the visual and aural media collections while if the
+      permission is not whitelisted the holder app can only access to the visual
+      and aural medial collections. Also the permission is immutably restricted
+      meaning that the whitelist state can be specified only at install time and
+      cannot change until the app is installed. For more details see
+      {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
      -->
     <permission android:name="android.permission.READ_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -916,6 +946,10 @@
          {@link #ACCESS_FINE_LOCATION}. Requesting this permission by itself doesn't give you
          location access.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -958,6 +992,10 @@
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
          targetSdkVersion}</a> is 16 or higher.</p>
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.READ_CALL_LOG"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -978,6 +1016,10 @@
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
          targetSdkVersion}</a> is 16 or higher.</p>
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.WRITE_CALL_LOG"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -991,6 +1033,10 @@
          abort the call altogether.
          <p>Protection level: dangerous
 
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
+
          @deprecated Applications should use {@link android.telecom.CallRedirectionService} instead
          of the {@link android.content.Intent#ACTION_NEW_OUTGOING_CALL} broadcast.
     -->
@@ -4616,8 +4662,9 @@
                 android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.PlatLogoActivity"
-                android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen"
+                android:theme="@style/Theme.DeviceDefault.DayNight"
                 android:configChanges="orientation|keyboardHidden"
+                android:icon="@drawable/platlogo"
                 android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.DisableCarModeActivity"
diff --git a/core/res/res/drawable-nodpi/android_logotype.xml b/core/res/res/drawable-nodpi/android_logotype.xml
new file mode 100644
index 0000000..bd298e4
--- /dev/null
+++ b/core/res/res/drawable-nodpi/android_logotype.xml
@@ -0,0 +1,42 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="290dp"
+        android:height="64dp"
+        android:viewportWidth="290.0"
+        android:viewportHeight="64.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M21.81,28.91c-7.44,0,-12.45,5.85,-12.45,13.37c0,7.52,5.01,13.37,12.45,13.37s12.45,-5.85,12.45,-13.37   C34.26,34.76,29.24,28.91,21.81,28.91 M20.13,20.55c6.02,0,11.03,3.09,13.37,6.43v-5.6l9.19,0l0,41.78l-6.24,0   c-1.63,0,-2.95,-1.32,-2.95,-2.95v-2.65C31.17,60.91,26.15,64,20.14,64C8.69,64,0,54.23,0,42.28C0,30.33,8.69,20.55,20.13,20.55"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M53.13,21.39l9.19,0l0,5.68c2.5,-4.18,7.27,-6.52,12.7,-6.52c9.69,0,15.96,6.85,15.96,17.46l0,25.15l-6.24,0   c-1.63,0,-2.95,-1.32,-2.95,-2.95l0,-20.7c0,-6.6,-3.34,-10.61,-8.69,-10.61c-6.1,0,-10.78,4.76,-10.78,13.7l0,20.55l-6.25,0   c-1.63,0,-2.95,-1.32,-2.95,-2.95L53.13,21.39z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M120.06,28.91c-7.43,0,-12.45,5.85,-12.45,13.37c0,7.52,5.01,13.37,12.45,13.37c7.43,0,12.45,-5.85,12.45,-13.37   C132.51,34.76,127.5,28.91,120.06,28.91 M118.39,20.55c6.02,0,11.03,3.09,13.37,6.43l0,-26.49l9.19,0l0,62.66h-6.24   c-1.63,0,-2.95,-1.32,-2.95,-2.95v-2.65c-2.34,3.34,-7.35,6.43,-13.37,6.43c-11.45,0,-20.14,-9.77,-20.14,-21.72   C98.25,30.33,106.94,20.55,118.39,20.55"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M151.39,21.39l9.19,0v7.44c1.59,-4.76,6.27,-7.86,11.03,-7.86c1.17,0,2.34,0.08,3.59,0.34v9.44c-1.59,-0.5,-2.92,-0.75,-4.59,-0.75   c-5.26,0,-10.03,4.43,-10.03,12.78l0,20.39l-6.24,0c-1.63,0,-2.95,-1.32,-2.95,-2.95L151.39,21.39z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M199.98,55.48c7.35,0,12.53,-5.77,12.53,-13.2c0,-7.44,-5.18,-13.2,-12.53,-13.2c-7.44,0,-12.62,5.77,-12.62,13.2   C187.37,49.71,192.55,55.48,199.98,55.48 M199.98,64c-12.37,0,-21.89,-9.61,-21.89,-21.72c0,-12.12,9.52,-21.73,21.89,-21.73   c12.37,0,21.89,9.61,21.89,21.73C221.87,54.39,212.35,64,199.98,64"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M229.32,21.39l9.19,0l0,41.78l-6.24,0c-1.63,0,-2.95,-1.32,-2.95,-2.95L229.32,21.39z M233.92,12.28   c-3.34,0,-6.18,-2.76,-6.18,-6.18c0,-3.34,2.84,-6.1,6.18,-6.1c3.43,0,6.1,2.76,6.1,6.1C240.02,9.53,237.34,12.28,233.92,12.28"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M267.87,28.91c-7.43,0,-12.45,5.85,-12.45,13.37c0,7.52,5.01,13.37,12.45,13.37c7.44,0,12.45,-5.85,12.45,-13.37   C280.32,34.76,275.31,28.91,267.87,28.91 M266.2,20.55c6.02,0,11.03,3.09,13.37,6.43l0,-26.49l9.19,0l0,62.66l-6.24,0   c-1.63,0,-2.95,-1.32,-2.95,-2.95v-2.65c-2.34,3.34,-7.35,6.43,-13.37,6.43c-11.44,0,-20.14,-9.77,-20.14,-21.72S254.76,20.55,266.2,20.55"/>
+</vector>
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index f5bbadc..19a296a 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2018 The Android Open Source Project
+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.
@@ -13,21 +13,15 @@
     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:name="vector"
-    android:width="640dp"
-    android:height="640dp"
-    android:viewportWidth="64"
-    android:viewportHeight="64">
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:name="bg"
-        android:pathData="M 27 43 L 32 43 C 38.075 43 43 38.075 43 32 C 43 25.925 38.075 21 32 21 C 25.925 21 21 25.925 21 32 L 21 64"
-        android:strokeColor="#6823a1"
-        android:strokeWidth="16"/>
+        android:fillColor="#FF000000"
+        android:pathData="M19.45,22.89l-10.250001,-10.249999l-2.6599998,2.6599998l-1.77,-1.7600002l4.43,-4.4300003l12.0199995,12.0199995l-1.7699986,1.7600002z"/>
     <path
-        android:name="fg"
-        android:pathData="M 29 43 L 32 43 C 38.075 43 43 38.075 43 32 C 43 25.925 38.075 21 32 21 C 25.925 21 21 25.925 21 32 L 21 64"
-        android:strokeColor="#ff0000"
-        android:strokeWidth="8"/>
+        android:fillColor="#FF000000"
+        android:pathData="M12,6a6,6 0,1 1,-6 6,6 6,0 0,1 6,-6m0,-2.5A8.5,8.5 0,1 0,20.5 12,8.51 8.51,0 0,0 12,3.5Z"/>
 </vector>
diff --git a/core/res/res/layout/platlogo_layout.xml b/core/res/res/layout/platlogo_layout.xml
new file mode 100644
index 0000000..4a4ad75
--- /dev/null
+++ b/core/res/res/layout/platlogo_layout.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:clipChildren="false"
+    android:background="@android:color/transparent">
+    <ImageView
+        android:id="@+id/text"
+        android:layout_width="400dp"
+        android:layout_height="wrap_content"
+        android:translationY="-100dp"
+        android:adjustViewBounds="true"
+        android:layout_marginBottom="-80dp"
+        android:layout_centerInParent="true"
+        android:src="@drawable/android_logotype"
+        android:tint="?android:attr/textColorPrimary"
+        />
+    <ImageView
+        android:id="@+id/one"
+        android:layout_width="200dp"
+        android:layout_height="200dp"
+        android:layout_marginLeft="24dp"
+        android:layout_below="@id/text"
+        android:layout_alignLeft="@id/text"
+        android:tint="?android:attr/textColorPrimary"
+        />
+    <ImageView
+        android:id="@+id/zero"
+        android:layout_width="200dp"
+        android:layout_height="200dp"
+        android:layout_marginRight="34dp"
+        android:layout_below="@id/text"
+        android:layout_alignRight="@id/text"
+        android:tint="?android:attr/textColorPrimary"
+        />
+</RelativeLayout>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index c307acb..1ab77cc 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -567,7 +567,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Beweg das Smartphone nach links."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Beweg das Smartphone nach rechts."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Bitte sieh direkt auf dein Gerät."</string>
-    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Richte die Smartphone-Kamera auf dein Gesicht."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Halte dein Gesicht direkt vor dein Smartphone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Zu viel Unruhe. Halte das Smartphone ruhig."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Bitte registriere dein Gesicht noch einmal."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Gesicht wird nicht mehr erkannt. Erneut versuchen."</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 7709cc3..f62b385 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -567,7 +567,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎Move phone to the left.‎‏‎‎‏‎"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎Move phone to the right.‎‏‎‎‏‎"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎Please look more directly at your device.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎Can’t see your face. Look at the phone.‎‏‎‎‏‎"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎Position your face directly in front of the phone.‎‏‎‎‏‎"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎Too much motion. Hold phone steady.‎‏‎‎‏‎"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎Please re-enroll your face.‎‏‎‎‏‎"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎No longer able to recognize face. Try again.‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index eaf1f56..fb79545 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -374,7 +374,7 @@
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Beren zati batzuk memoria modu iraunkorrean ezartzeko baimena ematen die aplikazioei. Horrela, beste aplikazioek erabilgarri duten memoria murritz daiteke eta tableta motel daiteke."</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Beren zati batzuk memorian modu iraunkorrean aktibo uztea baimentzen die aplikazioei. Horrela, beste aplikazioek memoria gutxiago izan lezakete erabilgarri eta telebistak motelago funtziona lezake."</string>
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Beren zati batzuk memoria modu iraunkorrean ezartzeko baimena ematen die aplikazioei. Horrela, beste aplikazioek erabilgarri duten memoria murritz daiteke eta telefonoa motel daiteke."</string>
-    <string name="permlab_foregroundService" msgid="3310786367649133115">"Exekutatu zerbitzuak aurreko planoan"</string>
+    <string name="permlab_foregroundService" msgid="3310786367649133115">"Abiarazi zerbitzuak aurreko planoan"</string>
     <string name="permdesc_foregroundService" msgid="6471634326171344622">"Aurreko planoko zerbitzuak erabiltzea baimentzen dio aplikazioari."</string>
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"neurtu aplikazioen biltegiratzeko tokia"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Bere kodea, datuak eta cache-tamainak eskuratzeko baimena ematen die aplikazioei."</string>
@@ -421,7 +421,7 @@
     <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telebistan, aplikazioak erabil ditzan."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telefonoan, aplikazioak erabil ditzan."</string>
     <string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"Atzitu kokapena atzeko planoan"</string>
-    <string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Baimen hau ematen bada kokapen zehatz edo gutxi gorabeherakorako sarbideaz gain, atzeko planoan exekutatu bitartean atzitu ahalko du aplikazioak kokapena."</string>
+    <string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Baimen hau ematen bada kokapen zehatz edo gutxi gorabeherakorako sarbideaz gain, atzeko planoan abian den bitartean atzitu ahalko du aplikazioak kokapena."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"aldatu audio-ezarpenak"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Audio-ezarpen orokorrak aldatzeko baimena ematen dio; besteak beste, bolumena eta irteerarako zer bozgorailu erabiltzen den."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"grabatu audioa"</string>
@@ -1176,7 +1176,7 @@
     <string name="wait" msgid="7147118217226317732">"Itxaron"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"Orriak ez du erantzuten.\n\nItxi egin nahi duzu?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplikazioa birbideratu da"</string>
-    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioa exekutatzen ari da."</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioa abian da."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioa lehenago abiarazi da."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Eskala"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"Erakutsi beti"</string>
@@ -1202,7 +1202,7 @@
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> prestatzen."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Aplikazioak abiarazten."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Bertsio-berritzea amaitzen."</string>
-    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> exekutatzen"</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> abian da"</string>
     <string name="heavy_weight_notification_detail" msgid="2304833848484424985">"Sakatu jokora itzultzeko"</string>
     <string name="heavy_weight_switcher_title" msgid="387882830435195342">"Aukeratu joko bat"</string>
     <string name="heavy_weight_switcher_text" msgid="4176781660362912010">"Funtzionamendu hobea izateko, joko hauetako bat baino ezin da egon irekita aldi berean."</string>
@@ -1440,7 +1440,7 @@
     <string name="ime_action_next" msgid="3138843904009813834">"Hurrengoa"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"Eginda"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Atzera"</string>
-    <string name="ime_action_default" msgid="2840921885558045721">"Exekutatu"</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"Abiarazi"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Markatu zenbakia \n<xliff:g id="NUMBER">%s</xliff:g> erabilita"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Sortu kontaktua\n<xliff:g id="NUMBER">%s</xliff:g> erabilita"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Aplikazio hauetako bat edo gehiago kontua orain eta etorkizunean atzitzeko baimena eskatzen ari dira."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index e18196f..4c8cc64 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -567,7 +567,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Move o teléfono cara á esquerda."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Move o teléfono cara á dereita."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Mira o dispositivo de forma máis directa."</string>
-    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Coloca a cara directamente fronte ao teléfono."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Coloca a cara directamente diante do teléfono."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Demasiado movemento. Non movas o teléfono."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Volve rexistrar a túa cara."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Xa non se pode recoñecer a cara. Téntao de novo."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index dfced05..7dc0b92 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1084,7 +1084,7 @@
     <string name="undo" msgid="7905788502491742328">"वापस लाएं"</string>
     <string name="redo" msgid="7759464876566803888">"फिर से करें"</string>
     <string name="autofill" msgid="3035779615680565188">"ऑटोमैटिक भरना"</string>
-    <string name="textSelectionCABTitle" msgid="5236850394370820357">"लेख चयन"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"टेक्स्ट चुनें"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"शब्दकोश में जोड़ें"</string>
     <string name="deleteText" msgid="6979668428458199034">"मिटाएं"</string>
     <string name="inputMethod" msgid="1653630062304567879">"इनपुट विधि"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 848a882..45efc5d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -416,7 +416,7 @@
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Consente all\'app di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'app di interferire con il funzionamento del GPS o di altre fonti di geolocalizzazione."</string>
     <string name="permlab_accessFineLocation" msgid="6265109654698562427">"accesso alla posizione esatta solo in primo piano"</string>
     <string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Questa app può recuperare la tua posizione esatta solo quando è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul telefono affinché l\'app possa usarli. Potrebbe aumentare il consumo della batteria."</string>
-    <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"Accesso alla posizione approssimativa (in base alla rete) solo in primo piano"</string>
+    <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"accesso alla posizione approssimativa (in base alla rete) solo in primo piano"</string>
     <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul tablet affinché l\'app possa usarli."</string>
     <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sulla TV affinché l\'app possa usarli."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul telefono affinché l\'app possa usarli."</string>
@@ -504,7 +504,7 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Consente all\'applicazione di comunicare con tag, schede e lettori NFC (Near Field Communication)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disattivazione blocco schermo"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Consente all\'applicazione di disattivare il blocco tastiera ed eventuali protezioni tramite password associate. Ad esempio, il telefono disattiva il blocco tastiera quando riceve una telefonata in arrivo e lo riattiva al termine della chiamata."</string>
-    <string name="permlab_requestPasswordComplexity" msgid="202650535669249674">"richiedi complessità del blocco schermo"</string>
+    <string name="permlab_requestPasswordComplexity" msgid="202650535669249674">"richiesta di complessità del blocco schermo"</string>
     <string name="permdesc_requestPasswordComplexity" msgid="4730994229754212347">"Consente all\'app di conoscere il livello di complessità del blocco schermo (alto, medio, basso o nessuno), che indica l\'intervallo di caratteri possibile e il tipo di blocco schermo. L\'app può inoltre suggerire agli utenti di aggiornare il blocco schermo a un livello specifico di complessità, ma gli utenti possono ignorare liberamente il suggerimento e uscire. Tieni presente che il blocco schermo non viene memorizzato come testo non crittografato, quindi l\'app non conosce la password esatta."</string>
     <string name="permlab_useBiometric" msgid="8837753668509919318">"utilizzo di hardware biometrico"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Consente all\'app di utilizzare hardware biometrico per eseguire l\'autenticazione"</string>
@@ -514,11 +514,11 @@
     <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Consente all\'app di utilizzare l\'hardware per il riconoscimento delle impronte digitali per eseguire l\'autenticazione"</string>
     <string name="permlab_audioWrite" msgid="2661772059799779292">"modifica della tua raccolta musicale"</string>
     <string name="permdesc_audioWrite" msgid="8888544708166230494">"Consente all\'app di modificare la tua raccolta musicale."</string>
-    <string name="permlab_videoWrite" msgid="128769316366746446">"Modifica della tua raccolta di video"</string>
+    <string name="permlab_videoWrite" msgid="128769316366746446">"modifica della tua raccolta di video"</string>
     <string name="permdesc_videoWrite" msgid="5448565757490640841">"Consente all\'app di modificare la tua raccolta di video."</string>
-    <string name="permlab_imagesWrite" msgid="3391306186247235510">"Modifica della tua raccolta di foto"</string>
+    <string name="permlab_imagesWrite" msgid="3391306186247235510">"modifica della tua raccolta di foto"</string>
     <string name="permdesc_imagesWrite" msgid="7073662756617474375">"Consente all\'app di modificare la tua raccolta di foto."</string>
-    <string name="permlab_mediaLocation" msgid="8675148183726247864">"Lettura delle posizioni dalla tua raccolta multimediale"</string>
+    <string name="permlab_mediaLocation" msgid="8675148183726247864">"lettura delle posizioni dalla tua raccolta multimediale"</string>
     <string name="permdesc_mediaLocation" msgid="2237023389178865130">"Consente all\'app di leggere le posizioni dalla tua raccolta multimediale."</string>
     <string name="biometric_dialog_default_title" msgid="881952973720613213">"Verifica la tua identità"</string>
     <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"Hardware biometrico non disponibile"</string>
@@ -550,9 +550,9 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona dell\'impronta digitale"</string>
-    <string name="permlab_manageFace" msgid="7262837876352591553">"gestisci l\'hardware per Sblocco col sorriso"</string>
+    <string name="permlab_manageFace" msgid="7262837876352591553">"gestione dell\'hardware per Sblocco col sorriso"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Consente all\'app di richiamare i metodi per aggiungere e rimuovere i modelli di volti."</string>
-    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utilizza l\'hardware per Sblocco col sorriso"</string>
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utilizzo dell\'hardware per Sblocco col sorriso"</string>
     <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Consente all\'app di utilizzare hardware per l\'autenticazione con Sblocco col sorriso"</string>
     <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Sblocco col sorriso"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Registra di nuovo il volto"</string>
@@ -601,7 +601,7 @@
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Consente a un\'applicazione di leggere le statistiche di sincronizzazione per un account, incluse la cronologia degli eventi di sincronizzazione e la quantità di dati sincronizzati."</string>
     <string name="permlab_sdcardRead" msgid="1438933556581438863">"lettura dei contenuti dell\'archivio condiviso"</string>
     <string name="permdesc_sdcardRead" msgid="1804941689051236391">"Consente all\'app di leggere i contenuti del tuo archivio condiviso."</string>
-    <string name="permlab_sdcardWrite" msgid="9220937740184960897">"modificare/eliminare i contenuti dell\'archivio condiviso"</string>
+    <string name="permlab_sdcardWrite" msgid="9220937740184960897">"modifica/eliminazione dei contenuti dell\'archivio condiviso"</string>
     <string name="permdesc_sdcardWrite" msgid="2834431057338203959">"Consente all\'app di modificare i contenuti del tuo archivio condiviso."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"invio/ricezione di chiamate SIP"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"Consente all\'app di effettuare e ricevere chiamate SIP."</string>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 5363ef9..039bc4d 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -90,6 +90,24 @@
         orientation. If zero, the value of rounded_corner_radius is used. -->
     <dimen name="rounded_corner_radius_bottom">0dp</dimen>
 
+    <!-- Default adjustment for the software rounded corners since corners are not perfectly
+        round. This value is used when retrieving the "radius" of the rounded corner in cases
+        where the exact bezier curve cannot be retrieved.  This value will be subtracted from
+        rounded_corner_radius to more accurately provide a "radius" for the rounded corner. -->
+    <dimen name="rounded_corner_radius_adjustment">0px</dimen>
+    <!-- Top adjustment for the software rounded corners since corners are not perfectly
+        round.  This value is used when retrieving the "radius" of the top rounded corner in cases
+        where the exact bezier curve cannot be retrieved.  This value will be subtracted from
+        rounded_corner_radius_top to more accurately provide a "radius" for the top rounded corners.
+         -->
+    <dimen name="rounded_corner_radius_top_adjustment">0px</dimen>
+    <!-- Bottom adjustment for the software rounded corners since corners are not perfectly
+        round.  This value is used when retrieving the "radius" of the bottom rounded corner in
+        cases where the exact bezier curve cannot be retrieved.  This value will be subtracted from
+        rounded_corner_radius_bottom to more accurately provide a "radius" for the bottom rounded
+        corners. -->
+    <dimen name="rounded_corner_radius_bottom_adjustment">0px</dimen>
+
     <!-- Width of the window of the divider bar used to resize docked stacks. -->
     <dimen name="docked_stack_divider_thickness">48dp</dimen>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6e03f5e..7c563f2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3703,6 +3703,9 @@
   <java-symbol type="dimen" name="rounded_corner_radius" />
   <java-symbol type="dimen" name="rounded_corner_radius_top" />
   <java-symbol type="dimen" name="rounded_corner_radius_bottom" />
+  <java-symbol type="dimen" name="rounded_corner_radius_adjustment" />
+  <java-symbol type="dimen" name="rounded_corner_radius_top_adjustment" />
+  <java-symbol type="dimen" name="rounded_corner_radius_bottom_adjustment" />
   <java-symbol type="bool" name="config_supportsRoundedCornersOnWindows" />
 
   <java-symbol type="string" name="config_defaultModuleMetadataProvider" />
@@ -3818,4 +3821,8 @@
 
   <java-symbol type="string" name="config_defaultSupervisionProfileOwnerComponent" />
   <java-symbol type="bool" name="config_inflateSignalStrength" />
+
+  <java-symbol type="drawable" name="android_logotype" />
+  <java-symbol type="layout" name="platlogo_layout" />
+
 </resources>
diff --git a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
index d5163e1..eff4826 100644
--- a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
+++ b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
@@ -64,7 +64,7 @@
     @Test
     public void testSingleByte() throws Exception {
         final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
-                new long[] { 10, 11 }).getFileDescriptor();
+                new long[] { 10, 11 }, new long[] {}).getFileDescriptor();
 
         final byte[] buf = new byte[1_000];
         assertEquals(buf.length, Os.read(fd, buf, 0, buf.length));
@@ -80,7 +80,7 @@
     @Test
     public void testRanges() throws Exception {
         final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
-                new long[] { 100, 200, 300, 400 }).getFileDescriptor();
+                new long[] { 100, 200, 300, 400 }, new long[] {}).getFileDescriptor();
 
         final byte[] buf = new byte[10];
         assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 90));
@@ -102,7 +102,7 @@
     @Test
     public void testEntireFile() throws Exception {
         final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
-                new long[] { 0, 5_000_000 }).getFileDescriptor();
+                new long[] { 0, 5_000_000 }, new long[] {}).getFileDescriptor();
 
         try (FileInputStream in = new FileInputStream(fd)) {
             int val;
@@ -115,7 +115,7 @@
     @Test
     public void testReadWrite() throws Exception {
         final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
-                new long[] { 100, 200, 300, 400 }).getFileDescriptor();
+                new long[] { 100, 200, 300, 400 }, new long[] {}).getFileDescriptor();
 
         // Redacted at first
         final byte[] buf = new byte[10];
@@ -168,4 +168,76 @@
         assertArrayEquals(new long[] { 100, 200 },
                 removeRange(new long[] { 100, 200 }, 150, 150));
     }
+
+    @Test
+    public void testFreeAtStart() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 10 }, new long[] {1}).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, (byte) 'f', (byte) 'r', (byte) 'e', (byte) 'e', 0, 0, 0, 0, 0 },
+                buf);
+    }
+
+    @Test
+    public void testFreeAtOffset() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 10 }, new long[] {3}).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, 0, 0, (byte) 'f', (byte) 'r', (byte) 'e', (byte) 'e', 0, 0, 0 },
+                buf);
+    }
+
+    @Test
+    public void testFreeAcrossRedactionStart() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 10 }, new long[] {0}).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, (byte) 'r', (byte) 'e', (byte) 'e', 0, 0, 0, 0, 0, 0 },
+                buf);
+    }
+
+    @Test
+    public void testFreeAcrossRedactionEnd() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 3 }, new long[] {2}).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, 0, (byte) 'f', 64, 64, 64, 64, 64, 64, 64 },
+                buf);
+    }
+
+    @Test
+    public void testFreeOutsideRedaction() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 8 }, new long[] { 8 }).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, 0, 0, 0, 0, 0, 0, 0, 64, 64 },
+                buf);
+    }
+
+    @Test
+    public void testFreeMultipleRedactions() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 2, 3, 4 }, new long[] { 0 }).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, (byte) 'r', 64, (byte) 'e', 64, 64, 64, 64, 64, 64 },
+                buf);
+    }
 }
diff --git a/packages/EasterEgg/AndroidManifest.xml b/packages/EasterEgg/AndroidManifest.xml
index c7dd40d..7f76a45 100644
--- a/packages/EasterEgg/AndroidManifest.xml
+++ b/packages/EasterEgg/AndroidManifest.xml
@@ -1,40 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2018 The Android Open 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.egg"
     android:versionCode="1"
     android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="28" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
 
     <application
-        android:icon="@drawable/icon"
+        android:icon="@drawable/q_icon"
         android:label="@string/app_name">
+        <activity android:name=".quares.QuaresActivity"
+            android:icon="@drawable/q_icon"
+            android:label="@string/q_egg_name"
+            android:theme="@style/QuaresTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
 
+                <category android:name="android.intent.category.DEFAULT" />
+                <!-- <category android:name="android.intent.category.LAUNCHER" /> -->
+                <category android:name="com.android.internal.category.PLATLOGO" />
+            </intent-filter>
+        </activity>
         <activity
             android:name=".paint.PaintActivity"
             android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
-            android:label="@string/app_name"
+            android:icon="@drawable/p_icon"
+            android:label="@string/p_egg_name"
             android:theme="@style/AppTheme">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <!--<category android:name="android.intent.category.LAUNCHER" />-->
-                <category android:name="com.android.internal.category.PLATLOGO" />
+
+                <!-- <category android:name="android.intent.category.DEFAULT" /> -->
+                <!-- <category android:name="android.intent.category.LAUNCHER" /> -->
+                <!-- <category android:name="com.android.internal.category.PLATLOGO" /> -->
             </intent-filter>
         </activity>
     </application>
diff --git a/packages/EasterEgg/res/drawable/icon_bg.xml b/packages/EasterEgg/res/drawable/icon_bg.xml
index c1553ce..659f98b 100644
--- a/packages/EasterEgg/res/drawable/icon_bg.xml
+++ b/packages/EasterEgg/res/drawable/icon_bg.xml
@@ -15,4 +15,4 @@
     limitations under the License.
 -->
 <color xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="#C5E1A5" />
\ No newline at end of file
+    android:color="@color/q_clue_text" />
diff --git a/packages/EasterEgg/res/drawable/icon.xml b/packages/EasterEgg/res/drawable/p_icon.xml
similarity index 100%
rename from packages/EasterEgg/res/drawable/icon.xml
rename to packages/EasterEgg/res/drawable/p_icon.xml
diff --git a/packages/EasterEgg/res/drawable/pixel_bg.xml b/packages/EasterEgg/res/drawable/pixel_bg.xml
new file mode 100644
index 0000000..4d4a113
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/pixel_bg.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Android Open 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:exitFadeDuration="100">
+    <item android:state_pressed="true">
+        <shape><solid android:color="@color/red"/></shape>
+    </item>
+    <item android:state_checked="true">
+        <shape><solid android:color="@color/pixel_on"/></shape>
+    </item>
+    <item>
+        <shape><solid android:color="@color/pixel_off"/></shape>
+    </item>
+</selector>
\ No newline at end of file
diff --git a/packages/EasterEgg/res/drawable/q.xml b/packages/EasterEgg/res/drawable/q.xml
new file mode 100644
index 0000000..75baa47
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/q.xml
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="@color/q_icon_fg"
+        android:pathData="M19.45,22.89l-10.250001,-10.249999l-2.6599998,2.6599998l-1.77,-1.7600002l4.43,-4.4300003l12.0199995,12.0199995l-1.7699986,1.7600002z"/>
+    <path
+        android:fillColor="@color/q_icon_fg"
+        android:pathData="M12,6a6,6 0,1 1,-6 6,6 6,0 0,1 6,-6m0,-2.5A8.5,8.5 0,1 0,20.5 12,8.51 8.51,0 0,0 12,3.5Z"/>
+</vector>
diff --git a/packages/EasterEgg/res/drawable/q_icon.xml b/packages/EasterEgg/res/drawable/q_icon.xml
new file mode 100644
index 0000000..ef4b0a3
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/q_icon.xml
@@ -0,0 +1,19 @@
+<!--
+    Copyright (C) 2019 The Android Open 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.
+-->
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/icon_bg"/>
+    <foreground android:drawable="@drawable/q_smaller"/>
+</adaptive-icon>
diff --git a/packages/EasterEgg/res/drawable/q_smaller.xml b/packages/EasterEgg/res/drawable/q_smaller.xml
new file mode 100644
index 0000000..c71dff0
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/q_smaller.xml
@@ -0,0 +1,23 @@
+<!--
+Copyright (C) 2019 The Android Open 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.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:insetBottom="5dp"
+        android:insetLeft="5dp"
+        android:insetRight="5dp"
+        android:insetTop="5dp"
+        android:drawable="@drawable/q" />
diff --git a/packages/EasterEgg/res/layout/activity_quares.xml b/packages/EasterEgg/res/layout/activity_quares.xml
new file mode 100644
index 0000000..dcc90f6
--- /dev/null
+++ b/packages/EasterEgg/res/layout/activity_quares.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Android Open 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:animateLayoutChanges="true"
+    tools:context="com.android.egg.quares.QuaresActivity">
+
+   <GridLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:alignmentMode="alignBounds"
+        android:id="@+id/grid"
+        />
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/label"
+        android:layout_gravity="center_horizontal|bottom"
+        android:gravity="center"
+        android:textSize="18dp"
+        android:visibility="gone"
+        android:drawablePadding="8dp"
+        android:padding="12dp"
+        android:backgroundTint="@color/q_clue_bg_correct"
+        android:textColor="@color/q_clue_text"
+        android:layout_marginBottom="48dp"
+        android:elevation="30dp"
+        />
+</FrameLayout>
diff --git a/packages/EasterEgg/res/values-night/q_colors.xml b/packages/EasterEgg/res/values-night/q_colors.xml
new file mode 100644
index 0000000..191bd94
--- /dev/null
+++ b/packages/EasterEgg/res/values-night/q_colors.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Android Open 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>
+    <color name="pixel_off">#000000</color>
+    <color name="pixel_on">#FFFFFF</color>
+
+    <color name="q_clue_bg">@color/navy</color>
+    <color name="q_clue_text">@color/tan</color>
+</resources>
\ No newline at end of file
diff --git a/packages/EasterEgg/res/values/q_colors.xml b/packages/EasterEgg/res/values/q_colors.xml
new file mode 100644
index 0000000..5e92c84
--- /dev/null
+++ b/packages/EasterEgg/res/values/q_colors.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Android Open 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>
+    <color name="emerald">#3ddc84</color>
+    <color name="red">#f8c734</color>
+    <color name="navy">#073042</color>
+    <color name="vapor">#d7effe</color>
+    <color name="tan">#eff7cf</color>
+
+    <color name="pixel_off">#FFFFFF</color>
+    <color name="pixel_on">#000000</color>
+
+    <color name="q_clue_bg">@color/tan</color>
+    <color name="q_clue_text">@color/navy</color>
+    <color name="q_clue_bg_correct">@color/emerald</color>
+
+    <color name="q_icon_fg">@color/emerald</color>
+</resources>
diff --git a/packages/EasterEgg/res/values/q_puzzles.xml b/packages/EasterEgg/res/values/q_puzzles.xml
new file mode 100644
index 0000000..7c2eff1
--- /dev/null
+++ b/packages/EasterEgg/res/values/q_puzzles.xml
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string-array name="puzzles">
+
+        <item>q</item>
+        <item>q</item>
+        <item>q</item>
+        <item>q</item>
+        <item>q</item>
+
+        <item>android:drawable/ic_info</item>
+
+        <item>android:drawable/stat_sys_adb</item>
+        <item>android:drawable/stat_sys_battery</item>
+        <item>android:drawable/stat_sys_phone_call</item>
+        <item>android:drawable/stat_sys_certificate_info</item>
+        <item>android:drawable/stat_sys_data_bluetooth</item>
+        <item>android:drawable/stat_sys_data_usb</item>
+        <item>android:drawable/stat_sys_download</item>
+        <item>android:drawable/stat_sys_gps_on</item>
+        <item>android:drawable/stat_sys_phone_call</item>
+        <item>android:drawable/stat_sys_tether_wifi</item>
+        <item>android:drawable/stat_sys_throttled</item>
+        <item>android:drawable/stat_sys_upload</item>
+
+        <item>android:drawable/stat_notify_car_mode</item>
+        <item>android:drawable/stat_notify_chat</item>
+        <item>android:drawable/stat_notify_disk_full</item>
+        <item>android:drawable/stat_notify_email_generic</item>
+        <item>android:drawable/stat_notify_error</item>
+        <item>android:drawable/stat_notify_gmail</item>
+        <item>android:drawable/stat_notify_missed_call</item>
+        <item>android:drawable/stat_notify_mmcc_indication_icn</item>
+        <item>android:drawable/stat_notify_more</item>
+        <item>android:drawable/stat_notify_rssi_in_range</item>
+        <item>android:drawable/stat_notify_sdcard</item>
+        <item>android:drawable/stat_notify_sdcard_prepare</item>
+        <item>android:drawable/stat_notify_sdcard_usb</item>
+        <item>android:drawable/stat_notify_sim_toolkit</item>
+        <item>android:drawable/stat_notify_sync</item>
+        <item>android:drawable/stat_notify_sync_anim0</item>
+        <item>android:drawable/stat_notify_sync_error</item>
+        <item>android:drawable/stat_notify_voicemail</item>
+
+        <item>android:drawable/ic_audio_alarm</item>
+        <item>android:drawable/ic_audio_alarm_mute</item>
+        <item>android:drawable/ic_bluetooth_share_icon</item>
+        <item>android:drawable/ic_bt_headphones_a2dp</item>
+        <item>android:drawable/ic_bt_headset_hfp</item>
+        <item>android:drawable/ic_bt_hearing_aid</item>
+        <item>android:drawable/ic_bt_laptop</item>
+        <item>android:drawable/ic_bt_misc_hid</item>
+        <item>android:drawable/ic_bt_network_pan</item>
+        <item>android:drawable/ic_bt_pointing_hid</item>
+        <item>android:drawable/ic_corp_badge</item>
+        <item>android:drawable/ic_expand_more</item>
+        <item>android:drawable/ic_faster_emergency</item>
+        <item>android:drawable/ic_file_copy</item>
+        <item>android:drawable/ic_info_outline_24</item>
+        <item>android:drawable/ic_lock</item>
+        <item>android:drawable/ic_lock_bugreport</item>
+        <item>android:drawable/ic_lock_open</item>
+        <item>android:drawable/ic_lock_power_off</item>
+        <item>android:drawable/ic_lockscreen_ime</item>
+        <item>android:drawable/ic_mode_edit</item>
+        <item>android:drawable/ic_phone</item>
+        <item>android:drawable/ic_qs_airplane</item>
+        <item>android:drawable/ic_qs_auto_rotate</item>
+        <item>android:drawable/ic_qs_battery_saver</item>
+        <item>android:drawable/ic_qs_bluetooth</item>
+        <item>android:drawable/ic_qs_dnd</item>
+        <item>android:drawable/ic_qs_flashlight</item>
+        <item>android:drawable/ic_qs_night_display_on</item>
+        <item>android:drawable/ic_restart</item>
+        <item>android:drawable/ic_screenshot</item>
+        <item>android:drawable/ic_settings_bluetooth</item>
+        <item>android:drawable/ic_signal_cellular_0_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_0_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_1_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_1_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_2_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_2_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_3_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_3_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_4_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_4_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_5_5_bar</item>
+        <item>android:drawable/ic_signal_location</item>
+        <item>android:drawable/ic_wifi_signal_0</item>
+        <item>android:drawable/ic_wifi_signal_1</item>
+        <item>android:drawable/ic_wifi_signal_2</item>
+        <item>android:drawable/ic_wifi_signal_3</item>
+        <item>android:drawable/ic_wifi_signal_4</item>
+        <item>android:drawable/perm_group_activity_recognition</item>
+        <item>android:drawable/perm_group_calendar</item>
+        <item>android:drawable/perm_group_call_log</item>
+        <item>android:drawable/perm_group_camera</item>
+        <item>android:drawable/perm_group_contacts</item>
+        <item>android:drawable/perm_group_location</item>
+        <item>android:drawable/perm_group_microphone</item>
+        <item>android:drawable/perm_group_phone_calls</item>
+        <item>android:drawable/perm_group_sensors</item>
+        <item>android:drawable/perm_group_sms</item>
+        <item>android:drawable/perm_group_storage</item>
+        <item>android:drawable/perm_group_visual</item>
+
+        <item>com.android.settings:drawable/ic_add_24dp</item>
+        <item>com.android.settings:drawable/ic_airplanemode_active</item>
+        <item>com.android.settings:drawable/ic_android</item>
+        <item>com.android.settings:drawable/ic_apps</item>
+        <item>com.android.settings:drawable/ic_arrow_back</item>
+        <item>com.android.settings:drawable/ic_arrow_down_24dp</item>
+        <item>com.android.settings:drawable/ic_battery_charging_full</item>
+        <item>com.android.settings:drawable/ic_battery_status_bad_24dp</item>
+        <item>com.android.settings:drawable/ic_battery_status_good_24dp</item>
+        <item>com.android.settings:drawable/ic_battery_status_maybe_24dp</item>
+        <item>com.android.settings:drawable/ic_call_24dp</item>
+        <item>com.android.settings:drawable/ic_cancel</item>
+        <item>com.android.settings:drawable/ic_cast_24dp</item>
+        <item>com.android.settings:drawable/ic_chevron_right_24dp</item>
+        <item>com.android.settings:drawable/ic_data_saver</item>
+        <item>com.android.settings:drawable/ic_delete</item>
+        <item>com.android.settings:drawable/ic_devices_other</item>
+        <item>com.android.settings:drawable/ic_devices_other_opaque_black</item>
+        <item>com.android.settings:drawable/ic_do_not_disturb_on_24dp</item>
+        <item>com.android.settings:drawable/ic_eject_24dp</item>
+        <item>com.android.settings:drawable/ic_expand_less</item>
+        <item>com.android.settings:drawable/ic_expand_more_inverse</item>
+        <item>com.android.settings:drawable/ic_folder_vd_theme_24</item>
+        <item>com.android.settings:drawable/ic_friction_lock_closed</item>
+        <item>com.android.settings:drawable/ic_gray_scale_24dp</item>
+        <item>com.android.settings:drawable/ic_headset_24dp</item>
+        <item>com.android.settings:drawable/ic_help</item>
+        <item>com.android.settings:drawable/ic_local_movies</item>
+        <item>com.android.settings:drawable/ic_lock</item>
+        <item>com.android.settings:drawable/ic_media_stream</item>
+        <item>com.android.settings:drawable/ic_network_cell</item>
+        <item>com.android.settings:drawable/ic_notifications</item>
+        <item>com.android.settings:drawable/ic_notifications_off_24dp</item>
+        <item>com.android.settings:drawable/ic_phone_info</item>
+        <item>com.android.settings:drawable/ic_photo_library</item>
+        <item>com.android.settings:drawable/ic_settings_accessibility</item>
+        <item>com.android.settings:drawable/ic_settings_accounts</item>
+        <item>com.android.settings:drawable/ic_settings_backup</item>
+        <item>com.android.settings:drawable/ic_settings_battery_white</item>
+        <item>com.android.settings:drawable/ic_settings_data_usage</item>
+        <item>com.android.settings:drawable/ic_settings_date_time</item>
+        <item>com.android.settings:drawable/ic_settings_delete</item>
+        <item>com.android.settings:drawable/ic_settings_display_white</item>
+        <item>com.android.settings:drawable/ic_settings_home</item>
+        <item>com.android.settings:drawable/ic_settings_location</item>
+        <item>com.android.settings:drawable/ic_settings_night_display</item>
+        <item>com.android.settings:drawable/ic_settings_open</item>
+        <item>com.android.settings:drawable/ic_settings_print</item>
+        <item>com.android.settings:drawable/ic_settings_privacy</item>
+        <item>com.android.settings:drawable/ic_settings_security_white</item>
+        <item>com.android.settings:drawable/ic_settings_sim</item>
+        <item>com.android.settings:drawable/ic_settings_wireless</item>
+        <item>com.android.settings:drawable/ic_storage</item>
+        <item>com.android.settings:drawable/ic_storage_white</item>
+        <item>com.android.settings:drawable/ic_suggestion_night_display</item>
+        <item>com.android.settings:drawable/ic_sync</item>
+        <item>com.android.settings:drawable/ic_system_update</item>
+        <item>com.android.settings:drawable/ic_videogame_vd_theme_24</item>
+        <item>com.android.settings:drawable/ic_volume_ringer_vibrate</item>
+        <item>com.android.settings:drawable/ic_volume_up_24dp</item>
+        <item>com.android.settings:drawable/ic_vpn_key</item>
+        <item>com.android.settings:drawable/ic_wifi_tethering</item>
+
+        <item>com.android.systemui:drawable/ic_alarm</item>
+        <item>com.android.systemui:drawable/ic_alarm_dim</item>
+        <item>com.android.systemui:drawable/ic_arrow_back</item>
+        <item>com.android.systemui:drawable/ic_bluetooth_connected</item>
+        <item>com.android.systemui:drawable/ic_brightness_thumb</item>
+        <item>com.android.systemui:drawable/ic_camera</item>
+        <item>com.android.systemui:drawable/ic_cast</item>
+        <item>com.android.systemui:drawable/ic_cast_connected</item>
+        <item>com.android.systemui:drawable/ic_cast_connected_fill</item>
+        <item>com.android.systemui:drawable/ic_close_white</item>
+        <item>com.android.systemui:drawable/ic_data_saver</item>
+        <item>com.android.systemui:drawable/ic_data_saver_off</item>
+        <item>com.android.systemui:drawable/ic_drag_handle</item>
+        <item>com.android.systemui:drawable/ic_headset</item>
+        <item>com.android.systemui:drawable/ic_headset_mic</item>
+        <item>com.android.systemui:drawable/ic_hotspot</item>
+        <item>com.android.systemui:drawable/ic_invert_colors</item>
+        <item>com.android.systemui:drawable/ic_location</item>
+        <item>com.android.systemui:drawable/ic_lockscreen_ime</item>
+        <item>com.android.systemui:drawable/ic_notifications_alert</item>
+        <item>com.android.systemui:drawable/ic_notifications_silence</item>
+        <item>com.android.systemui:drawable/ic_power_low</item>
+        <item>com.android.systemui:drawable/ic_power_saver</item>
+        <item>com.android.systemui:drawable/ic_qs_bluetooth_connecting</item>
+        <item>com.android.systemui:drawable/ic_qs_bluetooth_on</item>
+        <item>com.android.systemui:drawable/ic_qs_cancel</item>
+        <item>com.android.systemui:drawable/ic_qs_no_sim</item>
+        <item>com.android.systemui:drawable/ic_screenshot_delete</item>
+        <item>com.android.systemui:drawable/ic_settings</item>
+        <item>com.android.systemui:drawable/ic_swap_vert</item>
+        <item>com.android.systemui:drawable/ic_volume_alarm</item>
+        <item>com.android.systemui:drawable/ic_volume_alarm_mute</item>
+        <item>com.android.systemui:drawable/ic_volume_media</item>
+        <item>com.android.systemui:drawable/ic_volume_media_mute</item>
+        <item>com.android.systemui:drawable/ic_volume_ringer</item>
+        <item>com.android.systemui:drawable/ic_volume_ringer_mute</item>
+        <item>com.android.systemui:drawable/ic_volume_ringer_vibrate</item>
+        <item>com.android.systemui:drawable/ic_volume_voice</item>
+        <item>com.android.systemui:drawable/stat_sys_camera</item>
+        <item>com.android.systemui:drawable/stat_sys_managed_profile_status</item>
+        <item>com.android.systemui:drawable/stat_sys_mic_none</item>
+        <item>com.android.systemui:drawable/stat_sys_vpn_ic</item>
+
+    </string-array>
+</resources>
diff --git a/packages/EasterEgg/res/values/strings.xml b/packages/EasterEgg/res/values/strings.xml
index 32dbc97..b95ec6b 100644
--- a/packages/EasterEgg/res/values/strings.xml
+++ b/packages/EasterEgg/res/values/strings.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
 Copyright (C) 2018 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,5 +14,11 @@
     limitations under the License.
 -->
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <string name="app_name" translatable="false">PAINT.APK</string>
+    <string name="app_name" translatable="false">Android Q Easter Egg</string>
+
+    <!-- name of the Q easter egg, a nonogram-style icon puzzle -->
+    <string name="q_egg_name" translatable="false">Icon Quiz</string>
+
+    <!-- name of the P easter egg, a humble paint program -->
+    <string name="p_egg_name" translatable="false">PAINT.APK</string>
 </resources>
diff --git a/packages/EasterEgg/res/values/styles.xml b/packages/EasterEgg/res/values/styles.xml
index 44e2ce5..e576526 100644
--- a/packages/EasterEgg/res/values/styles.xml
+++ b/packages/EasterEgg/res/values/styles.xml
@@ -20,4 +20,16 @@
         <item name="android:windowLightNavigationBar">true</item>
     </style>
 
+    <style name="QuaresTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:windowShowWallpaper">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
+    </style>
+
 </resources>
diff --git a/packages/EasterEgg/src/com/android/egg/quares/Quare.kt b/packages/EasterEgg/src/com/android/egg/quares/Quare.kt
new file mode 100644
index 0000000..eb77362
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/quares/Quare.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2019 The Android Open 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.egg.quares
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.Icon
+import android.os.Parcel
+import android.os.Parcelable
+import java.util.ArrayList
+import kotlin.math.abs
+import kotlin.math.round
+
+class Quare(val width: Int, val height: Int, val depth: Int) : Parcelable {
+    private val data: IntArray = IntArray(width * height)
+    private val user: IntArray = data.copyOf()
+
+    private fun loadAndQuantize(bitmap8bpp: Bitmap) {
+        bitmap8bpp.getPixels(data, 0, width, 0, 0, width, height)
+        if (depth == 8) return
+        val s = (255f / depth)
+        for (i in 0 until data.size) {
+            var f = (data[i] ushr 24).toFloat() / s
+            // f = f.pow(0.75f) // gamma adjust for bolder lines
+            f *= 1.25f // brightness adjust for bolder lines
+            f.coerceAtMost(1f)
+            data[i] = (round(f) * s).toInt() shl 24
+        }
+    }
+
+    fun isBlank(): Boolean {
+        return data.sum() == 0
+    }
+
+    fun load(drawable: Drawable) {
+        val resized = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8)
+        val canvas = Canvas(resized)
+        drawable.setBounds(0, 0, width, height)
+        drawable.setTint(0xFF000000.toInt())
+        drawable.draw(canvas)
+        loadAndQuantize(resized)
+        resized.recycle()
+    }
+
+    fun load(context: Context, icon: Icon) {
+        icon.loadDrawable(context)?.let {
+            load(it)
+        }
+    }
+
+    fun bitmap(): Bitmap {
+        return Bitmap.createBitmap(data, width, height, Bitmap.Config.ALPHA_8)
+    }
+
+    fun getUserMark(x: Int, y: Int): Int {
+        return user[y * width + x] ushr 24
+    }
+
+    fun setUserMark(x: Int, y: Int, v: Int) {
+        user[y * width + x] = v shl 24
+    }
+
+    fun getDataAt(x: Int, y: Int): Int {
+        return data[y * width + x] ushr 24
+    }
+
+    fun check(): Boolean {
+        return data.contentEquals(user)
+    }
+
+    fun check(xSel: Int, ySel: Int): Boolean {
+        val xStart = if (xSel < 0) 0 else xSel
+        val xEnd = if (xSel < 0) width - 1 else xSel
+        val yStart = if (ySel < 0) 0 else ySel
+        val yEnd = if (ySel < 0) height - 1 else ySel
+        for (y in yStart..yEnd)
+            for (x in xStart..xEnd)
+                if (getDataAt(x, y) != getUserMark(x, y)) return false
+        return true
+    }
+
+    fun errors(): IntArray {
+        return IntArray(width * height) {
+            abs(data[it] - user[it])
+        }
+    }
+
+    fun getRowClue(y: Int): IntArray {
+        return getClue(-1, y)
+    }
+    fun getColumnClue(x: Int): IntArray {
+        return getClue(x, -1)
+    }
+    fun getClue(xSel: Int, ySel: Int): IntArray {
+        val arr = ArrayList<Int>()
+        var len = 0
+        val xStart = if (xSel < 0) 0 else xSel
+        val xEnd = if (xSel < 0) width - 1 else xSel
+        val yStart = if (ySel < 0) 0 else ySel
+        val yEnd = if (ySel < 0) height - 1 else ySel
+        for (y in yStart..yEnd)
+            for (x in xStart..xEnd)
+                if (getDataAt(x, y) != 0) {
+                    len++
+                } else if (len > 0) {
+                    arr.add(len)
+                    len = 0
+                }
+        if (len > 0) arr.add(len)
+        else if (arr.size == 0) arr.add(0)
+        return arr.toIntArray()
+    }
+
+    fun resetUserMarks() {
+        user.forEachIndexed { index, _ -> user[index] = 0 }
+    }
+
+    // Parcelable interface
+
+    override fun describeContents(): Int {
+        return 0
+    }
+
+    override fun writeToParcel(p: Parcel?, flags: Int) {
+        p?.let {
+            p.writeInt(width)
+            p.writeInt(height)
+            p.writeInt(depth)
+            p.writeIntArray(data)
+            p.writeIntArray(user)
+        }
+    }
+
+    companion object CREATOR : Parcelable.Creator<Quare> {
+        override fun createFromParcel(p: Parcel?): Quare {
+            return p!!.let {
+                Quare(
+                        p.readInt(), // width
+                        p.readInt(), // height
+                        p.readInt()  // depth
+                ).also {
+                    p.readIntArray(it.data)
+                    p.readIntArray(it.user)
+                }
+            }
+        }
+
+        override fun newArray(size: Int): Array<Quare?> {
+            return arrayOfNulls(size)
+        }
+    }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/quares/QuaresActivity.kt b/packages/EasterEgg/src/com/android/egg/quares/QuaresActivity.kt
new file mode 100644
index 0000000..ce439a9
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/quares/QuaresActivity.kt
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2019 The Android Open 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.egg.quares
+
+import android.app.Activity
+import android.content.Context
+import android.content.res.Configuration
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.Typeface
+import android.graphics.drawable.Icon
+import android.os.Bundle
+import android.text.StaticLayout
+import android.text.TextPaint
+import android.util.Log
+import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
+import android.widget.Button
+import android.widget.CompoundButton
+import android.widget.GridLayout
+
+import java.util.Random
+
+import com.android.egg.R
+
+const val TAG = "Quares"
+
+class QuaresActivity : Activity() {
+    private var q: Quare = Quare(16, 16, 1)
+    private var resId = 0
+    private var resName = ""
+    private var icon: Icon? = null
+
+    private lateinit var label: Button
+    private lateinit var grid: GridLayout
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        window.decorView.systemUiVisibility =
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+
+        actionBar?.hide()
+
+        setContentView(R.layout.activity_quares)
+
+        grid = findViewById(R.id.grid)
+        label = findViewById(R.id.label)
+
+        if (savedInstanceState != null) {
+            Log.v(TAG, "restoring puzzle from state")
+            q = savedInstanceState.getParcelable("q") ?: q
+            resId = savedInstanceState.getInt("resId")
+            resName = savedInstanceState.getString("resName", "")
+            loadPuzzle()
+        }
+
+        label.setOnClickListener { newPuzzle() }
+    }
+
+    override fun onResume() {
+        super.onResume()
+        if (resId == 0) {
+            // lazy init from onCreate
+            newPuzzle()
+        }
+        checkVictory()
+    }
+
+    override fun onSaveInstanceState(outState: Bundle) {
+        super.onSaveInstanceState(outState)
+
+        outState.putParcelable("q", q)
+        outState.putInt("resId", resId)
+        outState.putString("resName", resName)
+    }
+
+    fun newPuzzle() {
+        Log.v(TAG, "new puzzle...")
+
+        q.resetUserMarks()
+        val oldResId = resId
+        resId = android.R.drawable.stat_sys_warning
+        try {
+            for (tries in 0..3) {
+                val ar = resources.obtainTypedArray(R.array.puzzles)
+                val newName = ar.getString(Random().nextInt(ar.length()))
+                if (newName == null) continue
+
+                Log.v(TAG, "Looking for icon " + newName)
+
+                val pkg = getPackageNameForResourceName(newName)
+                val newId = packageManager.getResourcesForApplication(pkg)
+                        .getIdentifier(newName, "drawable", pkg)
+                if (newId == 0) {
+                    Log.v(TAG, "oops, " + newName + " doesn't resolve from pkg " + pkg)
+                } else if (newId != oldResId) {
+                    // got a good one
+                    resId = newId
+                    resName = newName
+                    break
+                }
+            }
+        } catch (e: RuntimeException) {
+            Log.v(TAG, "problem loading puzzle, using fallback", e)
+        }
+        loadPuzzle()
+    }
+
+    fun getPackageNameForResourceName(name: String): String {
+        return if (name.contains(":") && !name.startsWith("android:")) {
+            name.substring(0, name.indexOf(":"))
+        } else {
+            packageName
+        }
+    }
+
+    fun checkVictory() {
+        if (q.check()) {
+            val dp = resources.displayMetrics.density
+
+            val label: Button = findViewById(R.id.label)
+            label.text = resName.replace(Regex("^.*/"), "")
+            val drawable = icon?.loadDrawable(this)?.also {
+                it.setBounds(0, 0, (32 * dp).toInt(), (32 * dp).toInt())
+                it.setTint(label.currentTextColor)
+            }
+            label.setCompoundDrawables(drawable, null, null, null)
+
+            label.visibility = VISIBLE
+        } else {
+            label.visibility = GONE
+        }
+    }
+
+    fun loadPuzzle() {
+        Log.v(TAG, "loading " + resName + " at " + q.width + "x" + q.height)
+
+        val dp = resources.displayMetrics.density
+
+        icon = Icon.createWithResource(getPackageNameForResourceName(resName), resId)
+        q.load(this, icon!!)
+
+        if (q.isBlank()) {
+            // this is a really boring puzzle, let's try again
+            resId = 0
+            resName = ""
+            recreate()
+            return
+        }
+
+        grid.removeAllViews()
+        grid.columnCount = q.width + 1
+        grid.rowCount = q.height + 1
+
+        label.visibility = GONE
+
+        val orientation = resources.configuration.orientation
+
+        // clean this up a bit
+        val minSide = resources.configuration.smallestScreenWidthDp - 25 // ish
+        val size = (minSide / (q.height + 0.5) * dp).toInt()
+
+        val sb = StringBuffer()
+
+        for (j in 0 until grid.rowCount) {
+            for (i in 0 until grid.columnCount) {
+                val tv: View
+                val params = GridLayout.LayoutParams().also {
+                    it.width = size
+                    it.height = size
+                    it.setMargins(1, 1, 1, 1)
+                    it.rowSpec = GridLayout.spec(GridLayout.UNDEFINED, GridLayout.TOP) // UGH
+                }
+                val x = i - 1
+                val y = j - 1
+                if (i > 0 && j > 0) {
+                    if (i == 1 && j > 1) sb.append("\n")
+                    sb.append(if (q.getDataAt(x, y) == 0) " " else "X")
+                    tv = PixelButton(this)
+                    tv.isChecked = q.getUserMark(x, y) != 0
+                    tv.setOnClickListener {
+                        q.setUserMark(x, y, if (tv.isChecked) 0xFF else 0)
+                        val columnCorrect = (grid.getChildAt(i) as? ClueView)?.check(q) ?: false
+                        val rowCorrect = (grid.getChildAt(j*(grid.columnCount)) as? ClueView)
+                                ?.check(q) ?: false
+                        if (columnCorrect && rowCorrect) {
+                            checkVictory()
+                        } else {
+                            label.visibility = GONE
+                        }
+                    }
+                } else if (i == j) { // 0,0
+                    tv = View(this)
+                    tv.visibility = GONE
+                } else {
+                    tv = ClueView(this)
+                    if (j == 0) {
+                        tv.textRotation = 90f
+                        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+                            params.height /= 2
+                            tv.showText = false
+                        } else {
+                            params.height = (96 * dp).toInt()
+                        }
+                        if (x >= 0) {
+                            tv.setColumn(q, x)
+                        }
+                    }
+                    if (i == 0) {
+                        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+                            params.width /= 2
+                            tv.showText = false
+                        } else {
+                            params.width = (96 * dp).toInt()
+                        }
+                        if (y >= 0) {
+                            tv.setRow(q, y)
+                        }
+                    }
+                }
+                grid.addView(tv, params)
+            }
+        }
+
+        Log.v(TAG, "icon: \n" + sb)
+    }
+}
+
+class PixelButton(context: Context) : CompoundButton(context) {
+    init {
+        setBackgroundResource(R.drawable.pixel_bg)
+        isClickable = true
+        isEnabled = true
+    }
+}
+
+class ClueView(context: Context) : View(context) {
+    var row: Int = -1
+    var column: Int = -1
+    var textRotation: Float = 0f
+    var text: CharSequence = ""
+    var showText = true
+    val paint: TextPaint
+    val incorrectColor: Int
+    val correctColor: Int
+
+    init {
+        setBackgroundColor(0)
+        paint = TextPaint().also {
+            it.textSize = 14f * context.resources.displayMetrics.density
+            it.color = context.getColor(R.color.q_clue_text)
+            it.typeface = Typeface.DEFAULT_BOLD
+            it.textAlign = Paint.Align.CENTER
+        }
+        incorrectColor = context.getColor(R.color.q_clue_bg)
+        correctColor = context.getColor(R.color.q_clue_bg_correct)
+    }
+
+    fun setRow(q: Quare, row: Int): Boolean {
+        this.row = row
+        this.column = -1
+        this.textRotation = 0f
+        text = q.getRowClue(row).joinToString("-")
+        return check(q)
+    }
+    fun setColumn(q: Quare, column: Int): Boolean {
+        this.column = column
+        this.row = -1
+        this.textRotation = 90f
+        text = q.getColumnClue(column).joinToString("-")
+        return check(q)
+    }
+    fun check(q: Quare): Boolean {
+        val correct = q.check(column, row)
+        setBackgroundColor(if (correct) correctColor else incorrectColor)
+        return correct
+    }
+
+    override fun onDraw(canvas: Canvas?) {
+        super.onDraw(canvas)
+        if (!showText) return
+        canvas?.let {
+            val x = canvas.width / 2f
+            val y = canvas.height / 2f
+            var textWidth = canvas.width
+            if (textRotation != 0f) {
+                canvas.rotate(textRotation, x, y)
+                textWidth = canvas.height
+            }
+            val textLayout = StaticLayout.Builder.obtain(
+                    text, 0, text.length, paint, textWidth).build()
+            canvas.translate(x, y - textLayout.height / 2)
+            textLayout.draw(canvas)
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index 7f906f6..6d874ab 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -117,7 +117,7 @@
 
     public boolean isPreferred(BluetoothDevice device) {
         if (mService == null) return false;
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        return mService.getPriority(device) != BluetoothProfile.PRIORITY_OFF;
     }
 
     public int getPreferred(BluetoothDevice device) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
index de38e8a..b15ea98 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
@@ -18,15 +18,11 @@
 
 import android.content.Context;
 import android.net.NetworkTemplate;
-import android.os.ParcelUuid;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Utils class for data usage
  */
@@ -38,7 +34,7 @@
      */
     public static NetworkTemplate getMobileTemplate(Context context, int subId) {
         final TelephonyManager telephonyManager = context.getSystemService(
-                TelephonyManager.class);
+                TelephonyManager.class).createForSubscriptionId(subId);
         final SubscriptionManager subscriptionManager = context.getSystemService(
                 SubscriptionManager.class);
         final SubscriptionInfo info = subscriptionManager.getActiveSubscriptionInfo(subId);
@@ -49,23 +45,8 @@
             Log.i(TAG, "Subscription is not active: " + subId);
             return mobileAll;
         }
-        final ParcelUuid groupUuid = info.getGroupUuid();
-        if (groupUuid == null) {
-            Log.i(TAG, "Subscription doesn't have valid group uuid: " + subId);
-            return mobileAll;
-        }
 
-        // Otherwise merge other subscriberId to create new NetworkTemplate
-        final List<SubscriptionInfo> groupInfos = subscriptionManager.getSubscriptionsInGroup(
-                groupUuid);
-        final List<String> mergedSubscriberIds = new ArrayList<>();
-        for (SubscriptionInfo subInfo : groupInfos) {
-            final String subscriberId = telephonyManager.getSubscriberId(
-                    subInfo.getSubscriptionId());
-            if (subscriberId != null) {
-                mergedSubscriberIds.add(subscriberId);
-            }
-        }
-        return NetworkTemplate.normalize(mobileAll, mergedSubscriberIds.toArray(new String[0]));
+        // Use old API to build networkTemplate
+        return NetworkTemplate.normalize(mobileAll, telephonyManager.getMergedSubscriberIds());
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
index dc33cfe..821c0b3 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
@@ -44,7 +44,6 @@
 public class DataUsageUtilsTest {
 
     private static final int SUB_ID = 1;
-    private static final int SUB_ID_2 = 2;
     private static final String SUBSCRIBER_ID = "Test Subscriber";
     private static final String SUBSCRIBER_ID_2 = "Test Subscriber 2";
 
@@ -67,11 +66,11 @@
 
         mContext = spy(RuntimeEnvironment.application);
         when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
+        when(mTelephonyManager.createForSubscriptionId(SUB_ID)).thenReturn(mTelephonyManager);
         when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
         when(mTelephonyManager.getSubscriberId(SUB_ID)).thenReturn(SUBSCRIBER_ID);
-        when(mTelephonyManager.getSubscriberId(SUB_ID_2)).thenReturn(SUBSCRIBER_ID_2);
-        when(mInfo1.getSubscriptionId()).thenReturn(SUB_ID);
-        when(mInfo2.getSubscriptionId()).thenReturn(SUB_ID_2);
+        when(mTelephonyManager.getMergedSubscriberIds()).thenReturn(
+                new String[]{SUBSCRIBER_ID, SUBSCRIBER_ID_2});
 
         mInfos = new ArrayList<>();
         mInfos.add(mInfo1);
@@ -89,17 +88,7 @@
     }
 
     @Test
-    public void getMobileTemplate_groupUuidNull_returnMobileAll() {
-        when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(mInfo1);
-        when(mInfo1.getGroupUuid()).thenReturn(null);
-
-        final NetworkTemplate networkTemplate = DataUsageUtils.getMobileTemplate(mContext, SUB_ID);
-        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID)).isTrue();
-        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID_2)).isFalse();
-    }
-
-    @Test
-    public void getMobileTemplate_groupUuidExist_returnMobileMerged() {
+    public void getMobileTemplate_infoExisted_returnMobileMerged() {
         when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(mInfo1);
         when(mInfo1.getGroupUuid()).thenReturn(mParcelUuid);
 
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 9a0e9fc..c9d4957 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -46,6 +46,8 @@
     // We delayed destroy render context that subsequent render requests have chance to cancel it.
     // This is to avoid destroying then recreating render context in a very short time.
     private static final int DELAY_FINISH_RENDERING = 1000;
+    private static final int INTERVAL_WAIT_FOR_RENDERING = 100;
+    private static final int PATIENCE_WAIT_FOR_RENDERING = 5;
     private HandlerThread mWorker;
 
     @Override
@@ -80,7 +82,10 @@
         private StatusBarStateController mController;
         private final Runnable mFinishRenderingTask = this::finishRendering;
         private final boolean mNeedTransition;
+        private final Object mMonitor = new Object();
         private boolean mNeedRedraw;
+        // This variable can only be accessed in synchronized block.
+        private boolean mWaitingForRendering;
 
         GLEngine(Context context) {
             mNeedTransition = ActivityManager.isHighEndGfx()
@@ -122,6 +127,27 @@
             long duration = mNeedTransition || animationDuration != 0 ? animationDuration : 0;
             mWorker.getThreadHandler().post(
                     () -> mRenderer.updateAmbientMode(inAmbientMode, duration));
+            if (inAmbientMode && duration == 0) {
+                // This means that we are transiting from home to aod, to avoid
+                // race condition between window visibility and transition,
+                // we don't return until the transition is finished. See b/136643341.
+                waitForBackgroundRendering();
+            }
+        }
+
+        private void waitForBackgroundRendering() {
+            synchronized (mMonitor) {
+                try {
+                    mWaitingForRendering = true;
+                    for (int patience = 1; mWaitingForRendering; patience++) {
+                        mMonitor.wait(INTERVAL_WAIT_FOR_RENDERING);
+                        mWaitingForRendering &= patience < PATIENCE_WAIT_FOR_RENDERING;
+                    }
+                } catch (InterruptedException ex) {
+                } finally {
+                    mWaitingForRendering = false;
+                }
+            }
         }
 
         @Override
@@ -178,7 +204,8 @@
 
         @Override
         public void preRender() {
-            mWorker.getThreadHandler().post(this::preRenderInternal);
+            // This method should only be invoked from worker thread.
+            preRenderInternal();
         }
 
         private void preRenderInternal() {
@@ -212,7 +239,8 @@
 
         @Override
         public void requestRender() {
-            mWorker.getThreadHandler().post(this::requestRenderInternal);
+            // This method should only be invoked from worker thread.
+            requestRenderInternal();
         }
 
         private void requestRenderInternal() {
@@ -234,7 +262,21 @@
 
         @Override
         public void postRender() {
-            mWorker.getThreadHandler().post(this::scheduleFinishRendering);
+            // This method should only be invoked from worker thread.
+            notifyWaitingThread();
+            scheduleFinishRendering();
+        }
+
+        private void notifyWaitingThread() {
+            synchronized (mMonitor) {
+                if (mWaitingForRendering) {
+                    try {
+                        mWaitingForRendering = false;
+                        mMonitor.notify();
+                    } catch (IllegalMonitorStateException ex) {
+                    }
+                }
+            }
         }
 
         private void cancelFinishRenderingTask() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index 932e40c..a5857df 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -282,6 +282,7 @@
 
         if (mRestoredState == null) {
             updateState(STATE_AUTHENTICATING);
+            mNegativeButton.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
             final int hint = getHintStringResourceId();
             if (hint != 0) {
                 mErrorText.setText(hint);
@@ -319,8 +320,6 @@
             mDescriptionText.setText(descriptionText);
         }
 
-        mNegativeButton.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
-
         if (requiresConfirmation() && mRestoredState == null) {
             mPositiveButton.setVisibility(View.VISIBLE);
             mPositiveButton.setEnabled(false);
@@ -474,6 +473,8 @@
             mHandler.removeMessages(MSG_RESET_MESSAGE);
             mErrorText.setTextColor(mTextColor);
             mErrorText.setText(R.string.biometric_dialog_tap_confirm);
+            mErrorText.setContentDescription(
+                    getResources().getString(R.string.biometric_dialog_tap_confirm));
             mErrorText.setVisibility(View.VISIBLE);
             announceAccessibilityEvent();
             mPositiveButton.setVisibility(View.VISIBLE);
@@ -487,6 +488,7 @@
 
         if (newState == STATE_PENDING_CONFIRMATION || newState == STATE_AUTHENTICATED) {
             mNegativeButton.setText(R.string.cancel);
+            mNegativeButton.setContentDescription(getResources().getString(R.string.cancel));
         }
 
         updateIcon(mState, newState);
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
index 6a1f24a..45e97b3 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
@@ -84,7 +84,17 @@
     void updateAwake(boolean awake, long duration) {
         mAwake = awake;
         mAnimator.setDuration(duration);
-        animate();
+        if (!mAwake && duration == 0) {
+            // We are transiting from home to aod,
+            // since main thread is waiting for rendering finished, we only need draw
+            // the last state directly, which is a black screen.
+            mReveal = MIN_REVEAL;
+            mRevealListener.onRevealStart();
+            mRevealListener.onRevealStateChanged();
+            mRevealListener.onRevealEnd();
+        } else {
+            animate();
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4dcb9f9..57bf536 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -210,6 +210,7 @@
     private boolean mBootCompleted;
     private boolean mBootSendUserPresent;
     private boolean mShuttingDown;
+    private boolean mDozing;
 
     /** High level access to the power manager for WakeLocks */
     private PowerManager mPM;
@@ -713,11 +714,10 @@
                 com.android.keyguard.R.bool.config_enableKeyguardService)) {
             setShowingLocked(!shouldWaitForProvisioning()
                     && !mLockPatternUtils.isLockScreenDisabled(
-                            KeyguardUpdateMonitor.getCurrentUser()),
-                    mAodShowing, true /* forceCallbacks */);
+                            KeyguardUpdateMonitor.getCurrentUser()), true /* forceCallbacks */);
         } else {
             // The system's keyguard is disabled or missing.
-            setShowingLocked(false, mAodShowing, true);
+            setShowingLocked(false /* showing */, true /* forceCallbacks */);
         }
 
         mStatusBarKeyguardViewManager =
@@ -1326,7 +1326,7 @@
             if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
                 if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
                 // Without this, settings is not enabled until the lock screen first appears
-                setShowingLocked(false, mAodShowing);
+                setShowingLocked(false);
                 hideLocked();
                 return;
             }
@@ -1742,6 +1742,9 @@
 
     private void updateActivityLockScreenState(boolean showing, boolean aodShowing) {
         mUiOffloadThread.submit(() -> {
+            if (DEBUG) {
+                Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ")");
+            }
             try {
                 ActivityTaskManager.getService().setLockScreenShown(showing, aodShowing);
             } catch (RemoteException e) {
@@ -1767,10 +1770,10 @@
                 if (DEBUG) Log.d(TAG, "handleShow");
             }
 
-            setShowingLocked(true, mAodShowing);
-            mStatusBarKeyguardViewManager.show(options);
             mHiding = false;
             mWakeAndUnlocking = false;
+            setShowingLocked(true);
+            mStatusBarKeyguardViewManager.show(options);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             adjustStatusBarLocked();
@@ -1877,7 +1880,7 @@
 
             if (!mHiding) {
                 // Tell ActivityManager that we canceled the keyguardExitAnimation.
-                setShowingLocked(mShowing, mAodShowing, true /* force */);
+                setShowingLocked(mShowing, true /* force */);
                 return;
             }
             mHiding = false;
@@ -1898,8 +1901,8 @@
                 playSounds(false);
             }
 
+            setShowingLocked(false);
             mWakeAndUnlocking = false;
-            setShowingLocked(false, mAodShowing);
             mDismissCallbackRegistry.notifyDismissSucceeded();
             mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
             resetKeyguardDonePendingLocked();
@@ -1959,7 +1962,7 @@
         Trace.beginSection("KeyguardViewMediator#handleVerifyUnlock");
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
-            setShowingLocked(true, mAodShowing);
+            setShowingLocked(true);
             mStatusBarKeyguardViewManager.dismissAndCollapse();
         }
         Trace.endSection();
@@ -2106,6 +2109,8 @@
         pw.print("  mDeviceInteractive: "); pw.println(mDeviceInteractive);
         pw.print("  mGoingToSleep: "); pw.println(mGoingToSleep);
         pw.print("  mHiding: "); pw.println(mHiding);
+        pw.print("  mDozing: "); pw.println(mDozing);
+        pw.print("  mAodShowing: "); pw.println(mAodShowing);
         pw.print("  mWaitingUntilKeyguardVisible: "); pw.println(mWaitingUntilKeyguardVisible);
         pw.print("  mKeyguardDonePending: "); pw.println(mKeyguardDonePending);
         pw.print("  mHideAnimationRun: "); pw.println(mHideAnimationRun);
@@ -2116,10 +2121,14 @@
     }
 
     /**
-     * @param aodShowing true when AOD - or ambient mode - is showing.
+     * @param dozing true when AOD - or ambient mode - is showing.
      */
-    public void setAodShowing(boolean aodShowing) {
-        setShowingLocked(mShowing, aodShowing);
+    public void setDozing(boolean dozing) {
+        if (dozing == mDozing) {
+            return;
+        }
+        mDozing = dozing;
+        setShowingLocked(mShowing);
     }
 
     /**
@@ -2140,19 +2149,18 @@
         }
     }
 
-    private void setShowingLocked(boolean showing, boolean aodShowing) {
-        setShowingLocked(showing, aodShowing, false /* forceCallbacks */);
+    private void setShowingLocked(boolean showing) {
+        setShowingLocked(showing, false /* forceCallbacks */);
     }
 
-    private void setShowingLocked(boolean showing, boolean aodShowing, boolean forceCallbacks) {
+    private void setShowingLocked(boolean showing, boolean forceCallbacks) {
+        final boolean aodShowing = mDozing && !mWakeAndUnlocking;
         final boolean notifyDefaultDisplayCallbacks = showing != mShowing
                 || aodShowing != mAodShowing || forceCallbacks;
+        mShowing = showing;
+        mAodShowing = aodShowing;
         if (notifyDefaultDisplayCallbacks) {
-            mShowing = showing;
-            mAodShowing = aodShowing;
-            if (notifyDefaultDisplayCallbacks) {
-                notifyDefaultDisplayCallbacks(showing);
-            }
+            notifyDefaultDisplayCallbacks(showing);
             updateActivityLockScreenState(showing, aodShowing);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index c44f953..cbaf85c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -22,6 +22,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.util.Log;
 import android.util.Pools;
 import android.view.DisplayCutout;
@@ -88,7 +89,7 @@
     private int[] mTmpTwoArray = new int[2];
     private boolean mHeadsUpGoingAway;
     private int mStatusBarState;
-    private Rect mTouchableRegion = new Rect();
+    private Region mTouchableRegion = new Region();
 
     private AnimationStateHandler mAnimationStateHandler;
 
@@ -365,10 +366,11 @@
         info.touchableRegion.set(calculateTouchableRegion());
     }
 
-    public Rect calculateTouchableRegion() {
+    public Region calculateTouchableRegion() {
         if (!hasPinnedHeadsUp()) {
             mTouchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
             updateRegionForNotch(mTouchableRegion);
+
         } else {
             NotificationEntry topEntry = getTopEntry();
             if (topEntry.isChildInGroup()) {
@@ -388,7 +390,7 @@
         return mTouchableRegion;
     }
 
-    private void updateRegionForNotch(Rect region) {
+    private void updateRegionForNotch(Region region) {
         DisplayCutout cutout = mStatusBarWindowView.getRootWindowInsets().getDisplayCutout();
         if (cutout == null) {
             return;
@@ -460,6 +462,8 @@
         super.dumpInternal(fd, pw, args);
         pw.print("  mBarState=");
         pw.println(mStatusBarState);
+        pw.print("  mTouchableRegion=");
+        pw.println(mTouchableRegion);
     }
 
     ///////////////////////////////////////////////////////////////////////////////////////////////
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 7430f7c..37855ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -38,6 +38,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.PowerManager;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -676,9 +677,10 @@
 
     private Rect calculateGestureExclusionRect() {
         Rect exclusionRect = null;
-        if (isFullyCollapsed()) {
+        Region touchableRegion = mHeadsUpManager.calculateTouchableRegion();
+        if (isFullyCollapsed() && touchableRegion != null) {
             // Note: The heads up manager also calculates the non-pinned touchable region
-            exclusionRect = mHeadsUpManager.calculateTouchableRegion();
+            exclusionRect = touchableRegion.getBounds();
         }
         return exclusionRect != null
                 ? exclusionRect
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 4392c35e..458cde4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1938,6 +1938,7 @@
 
         if (start) {
             mNotificationPanel.startWaitingForOpenPanelGesture();
+            setPanelExpanded(true);
         } else {
             mNotificationPanel.stopWaitingForOpenPanelGesture(velocity);
         }
@@ -3435,7 +3436,7 @@
         mNotificationPanel.resetViews(dozingAnimated);
 
         updateQsExpansionEnabled();
-        mKeyguardViewMediator.setAodShowing(mDozing);
+        mKeyguardViewMediator.setDozing(mDozing);
 
         mEntryManager.updateNotifications();
         updateDozingState();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index b21ba09..4562763 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -163,7 +163,8 @@
                         | PhoneStateListener.LISTEN_CALL_STATE
                         | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
                         | PhoneStateListener.LISTEN_DATA_ACTIVITY
-                        | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE);
+                        | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE
+                        | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
         mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.MOBILE_DATA),
                 true, mObserver);
         mContext.getContentResolver().registerContentObserver(Global.getUriFor(
@@ -636,6 +637,13 @@
 
             updateTelephony();
         }
+
+        @Override
+        public void onActiveDataSubscriptionIdChanged(int subId) {
+            if (DEBUG) Log.d(mTag, "onActiveDataSubscriptionIdChanged: subId=" + subId);
+            updateDataSim();
+            updateTelephony();
+        }
     };
 
     static class MobileIconGroup extends SignalController.IconGroup {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index e66e596..f7e825e 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1027,7 +1027,12 @@
                 log(str);
             }
             mLocalLog.log(str);
-            if (validatePhoneId(phoneId)) {
+            // for service state updates, don't notify clients when subId is invalid. This prevents
+            // us from sending incorrect notifications like b/133140128
+            // In the future, we can remove this logic for every notification here and add a
+            // callback so listeners know when their PhoneStateListener's subId becomes invalid, but
+            // for now we use the simplest fix.
+            if (validatePhoneId(phoneId) && SubscriptionManager.isValidSubscriptionId(subId)) {
                 mServiceState[phoneId] = state;
 
                 for (Record r : mRecords) {
@@ -1059,7 +1064,8 @@
                     }
                 }
             } else {
-                log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId);
+                log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId
+                        + " or subId=" + subId);
             }
             handleRemoveListLocked();
         }
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index bc7da3f..30a3563 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -413,15 +413,15 @@
             try {
                 synchronized (mLock) {
                     if (mNightMode != mode) {
-                        if (UserManager.get(getContext()).isPrimaryUser()) {
-                            SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME,
-                                    Integer.toString(mode));
-                        }
-
                         // Only persist setting if not in car mode
                         if (!mCarModeEnabled) {
                             Secure.putIntForUser(getContext().getContentResolver(),
                                     Secure.UI_NIGHT_MODE, mode, user);
+
+                            if (UserManager.get(getContext()).isPrimaryUser()) {
+                                SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME,
+                                        Integer.toString(mode));
+                            }
                         }
 
                         mNightMode = mode;
diff --git a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
index c52921e..16cf7ee 100644
--- a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
@@ -75,6 +75,14 @@
         mMaster = master;
         mLock = lock;
         mUserId = userId;
+        updateIsSetupComplete(userId);
+    }
+
+    /** Updates whether setup is complete for current user */
+    private void updateIsSetupComplete(@UserIdInt int userId) {
+        final String setupComplete = Settings.Secure.getStringForUser(
+                getContext().getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, userId);
+        mSetupComplete = "1".equals(setupComplete);
     }
 
     /**
@@ -143,9 +151,7 @@
                     + ", disabled=" + disabled + ", mDisabled=" + mDisabled);
         }
 
-        final String setupComplete = Settings.Secure.getStringForUser(
-                getContext().getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
-        mSetupComplete = "1".equals(setupComplete);
+        updateIsSetupComplete(mUserId);
         mDisabled = disabled;
 
         updateServiceInfoLocked();
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index e107c9a..08c1bb5 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -86,9 +86,9 @@
 
     private static final String TAG = "RollbackManager";
 
-    // Rollbacks expire after 48 hours.
+    // Rollbacks expire after 14 days.
     private static final long DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS =
-            TimeUnit.HOURS.toMillis(48);
+            TimeUnit.DAYS.toMillis(14);
 
     // Lock used to synchronize accesses to in-memory rollback data
     // structures. By convention, methods with the suffix "Locked" require
@@ -1289,7 +1289,8 @@
 
 
     private boolean packageVersionsEqual(VersionedPackage a, VersionedPackage b) {
-        return a.getPackageName().equals(b.getPackageName())
+        return a != null && b != null
+            && a.getPackageName().equals(b.getPackageName())
             && a.getLongVersionCode() == b.getLongVersionCode();
     }
 
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 9908b36..b0f1e5d 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1172,8 +1172,16 @@
                 return false;
             }
             final int displayId = display.getDisplayId();
-            return displayId == DEFAULT_DISPLAY
-                    || mWindowManagerInternal.shouldShowSystemDecorOnDisplay(displayId);
+            if (displayId == DEFAULT_DISPLAY) {
+                return true;
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return mWindowManagerInternal.shouldShowSystemDecorOnDisplay(displayId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
 
         void forEachDisplayConnector(Consumer<DisplayConnector> action) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 758cd28..6f60d33 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -10788,7 +10788,6 @@
      * @param callback Callback will be triggered once it succeeds or failed.
      *                 See {@link TelephonyManager.SetOpportunisticSubscriptionResult}
      *                 for more details. Pass null if don't care about the result.
-     *
      */
     public void setPreferredOpportunisticDataSubscription(int subId, boolean needValidation,
             @Nullable @CallbackExecutor Executor executor, @Nullable Consumer<Integer> callback) {
@@ -10796,6 +10795,12 @@
         try {
             IOns iOpportunisticNetworkService = getIOns();
             if (iOpportunisticNetworkService == null) {
+                if (executor == null || callback == null) {
+                    return;
+                }
+                Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
+                    callback.accept(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
+                }));
                 return;
             }
             ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
@@ -10877,9 +10882,16 @@
                 if (executor == null || callback == null) {
                     return;
                 }
-                Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
-                    callback.accept(UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS);
-                }));
+                if (iOpportunisticNetworkService == null) {
+                    /* Todo<b/130595455> passing unknown due to lack of good error codes */
+                    Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
+                        callback.accept(UPDATE_AVAILABLE_NETWORKS_UNKNOWN_FAILURE);
+                    }));
+                } else {
+                    Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
+                        callback.accept(UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS);
+                    }));
+                }
                 return;
             }
             IUpdateAvailableNetworksCallback callbackStub =
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index beff0c6..1b002ca 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -960,6 +960,7 @@
     }
 
     @Test
+    @Ignore("b/136605788")
     public void testEnableRollbackTimeoutFailsRollback() throws Exception {
         try {
             RollbackTestUtils.adoptShellPermissionIdentity(