Merge "Add more intelligence to bluetooth connection state" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index cb63aaa..d7fdb2d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22674,12 +22674,14 @@
 
   public static class Build.VERSION {
     ctor public Build.VERSION();
+    field public static final java.lang.String BASE_OS;
     field public static final java.lang.String CODENAME;
     field public static final java.lang.String INCREMENTAL;
     field public static final int PREVIEW_SDK_INT;
     field public static final java.lang.String RELEASE;
     field public static final deprecated java.lang.String SDK;
     field public static final int SDK_INT;
+    field public static final java.lang.String SECURITY_PATCH;
   }
 
   public static class Build.VERSION_CODES {
diff --git a/api/system-current.txt b/api/system-current.txt
index a9bc944..3c88e59 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24618,12 +24618,14 @@
 
   public static class Build.VERSION {
     ctor public Build.VERSION();
+    field public static final java.lang.String BASE_OS;
     field public static final java.lang.String CODENAME;
     field public static final java.lang.String INCREMENTAL;
     field public static final int PREVIEW_SDK_INT;
     field public static final java.lang.String RELEASE;
     field public static final deprecated java.lang.String SDK;
     field public static final int SDK_INT;
+    field public static final java.lang.String SECURITY_PATCH;
   }
 
   public static class Build.VERSION_CODES {
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index 8e0eab2..e71e49f 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -98,9 +98,19 @@
             HighSpeedVideoConfiguration[] highSpeedVideoConfigurations,
             ReprocessFormatsMap inputOutputFormatsMap,
             boolean listHighResolution) {
-        mConfigurations = checkArrayElementsNotNull(configurations, "configurations");
-        mMinFrameDurations = checkArrayElementsNotNull(minFrameDurations, "minFrameDurations");
-        mStallDurations = checkArrayElementsNotNull(stallDurations, "stallDurations");
+
+        if (configurations == null) {
+            // If no color configurations exist, ensure depth ones do
+            checkArrayElementsNotNull(depthConfigurations, "depthConfigurations");
+            mConfigurations = new StreamConfiguration[0];
+            mMinFrameDurations = new StreamConfigurationDuration[0];
+            mStallDurations = new StreamConfigurationDuration[0];
+        } else {
+            mConfigurations = checkArrayElementsNotNull(configurations, "configurations");
+            mMinFrameDurations = checkArrayElementsNotNull(minFrameDurations, "minFrameDurations");
+            mStallDurations = checkArrayElementsNotNull(stallDurations, "stallDurations");
+        }
+
         mListHighResolution = listHighResolution;
 
         if (depthConfigurations == null) {
@@ -124,7 +134,7 @@
         }
 
         // For each format, track how many sizes there are available to configure
-        for (StreamConfiguration config : configurations) {
+        for (StreamConfiguration config : mConfigurations) {
             int fmt = config.getFormat();
             SparseIntArray map = null;
             if (config.isOutput()) {
@@ -159,7 +169,8 @@
                     mDepthOutputFormats.get(config.getFormat()) + 1);
         }
 
-        if (mOutputFormats.indexOfKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) < 0) {
+        if (configurations != null &&
+                mOutputFormats.indexOfKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) < 0) {
             throw new AssertionError(
                     "At least one stream configuration for IMPLEMENTATION_DEFINED must exist");
         }
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index a0162f7..2374899 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -157,6 +157,17 @@
         public static final String RELEASE = getString("ro.build.version.release");
 
         /**
+         * The base OS build the product is based on.
+         */
+        public static final String BASE_OS = SystemProperties.get("ro.build.version.base_os", "");
+
+        /**
+         * The user-visible security patch level.
+         */
+        public static final String SECURITY_PATCH = SystemProperties.get(
+                "ro.build.version.security_patch", "");
+
+        /**
          * The user-visible SDK version of the framework in its raw String
          * representation; use {@link #SDK_INT} instead.
          *
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 010cb27..5b042c6 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3308,7 +3308,7 @@
                 mSelectionBounds.set(
                         primaryHorizontal,
                         layout.getLineTop(line),
-                        primaryHorizontal + 1,
+                        primaryHorizontal,
                         layout.getLineTop(line + 1) + mHandleHeight);
             }
             // Take TextView's padding and scroll into account.
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index dd7ea45..a7bdbe0 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -2907,13 +2907,18 @@
                     mLastHasRightStableInset = hasRightStableInset;
                 }
 
-                updateColorViewInt(mStatusColorViewState, sysUiVisibility, mStatusBarColor,
-                        mLastTopInset, false /* matchVertical */, animate && !disallowAnimate);
-
                 boolean navBarToRightEdge = mLastBottomInset == 0 && mLastRightInset > 0;
                 int navBarSize = navBarToRightEdge ? mLastRightInset : mLastBottomInset;
                 updateColorViewInt(mNavigationColorViewState, sysUiVisibility, mNavigationBarColor,
-                        navBarSize, navBarToRightEdge, animate && !disallowAnimate);
+                        navBarSize, navBarToRightEdge, 0 /* rightInset */,
+                        animate && !disallowAnimate);
+
+                boolean statusBarNeedsRightInset = navBarToRightEdge
+                        && mNavigationColorViewState.present;
+                int statusBarRightInset = statusBarNeedsRightInset ? mLastRightInset : 0;
+                updateColorViewInt(mStatusColorViewState, sysUiVisibility, mStatusBarColor,
+                        mLastTopInset, false /* matchVertical */, statusBarRightInset,
+                        animate && !disallowAnimate);
             }
 
             // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
@@ -2966,15 +2971,17 @@
          * @param size the current size in the non-parent-matching dimension.
          * @param verticalBar if true the view is attached to a vertical edge, otherwise to a
          *                    horizontal edge,
+         * @param rightMargin rightMargin for the color view.
          * @param animate if true, the change will be animated.
          */
         private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
-                int size, boolean verticalBar, boolean animate) {
-            boolean show = size > 0 && (sysUiVis & state.systemUiHideFlag) == 0
+                int size, boolean verticalBar, int rightMargin, boolean animate) {
+            state.present = size > 0 && (sysUiVis & state.systemUiHideFlag) == 0
                     && (getAttributes().flags & state.hideWindowFlag) == 0
-                    && (getAttributes().flags & state.translucentFlag) == 0
-                    && (color & Color.BLACK) != 0
                     && (getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
+            boolean show = state.present
+                    && (color & Color.BLACK) != 0
+                    && (getAttributes().flags & state.translucentFlag) == 0;
 
             boolean visibilityChanged = false;
             View view = state.view;
@@ -2993,7 +3000,10 @@
                     view.setVisibility(INVISIBLE);
                     state.targetVisibility = VISIBLE;
 
-                    addView(view, new LayoutParams(resolvedWidth, resolvedHeight, resolvedGravity));
+                    LayoutParams lp = new LayoutParams(resolvedWidth, resolvedHeight,
+                            resolvedGravity);
+                    lp.rightMargin = rightMargin;
+                    addView(view, lp);
                     updateColorViewTranslations();
                 }
             } else {
@@ -3003,10 +3013,11 @@
                 if (show) {
                     LayoutParams lp = (LayoutParams) view.getLayoutParams();
                     if (lp.height != resolvedHeight || lp.width != resolvedWidth
-                            || lp.gravity != resolvedGravity) {
+                            || lp.gravity != resolvedGravity || lp.rightMargin != rightMargin) {
                         lp.height = resolvedHeight;
                         lp.width = resolvedWidth;
                         lp.gravity = resolvedGravity;
+                        lp.rightMargin = rightMargin;
                         view.setLayoutParams(lp);
                     }
                     view.setBackgroundColor(color);
@@ -5022,6 +5033,7 @@
     private static class ColorViewState {
         View view = null;
         int targetVisibility = View.INVISIBLE;
+        boolean present = false;
 
         final int id;
         final int systemUiHideFlag;
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 41628d0..9761661 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -194,8 +194,16 @@
             mContext.getResources().getDisplayMetrics().widthPixels,
             mContext.getResources().getDisplayMetrics().heightPixels);
 
-        return Rect.intersects(mContentRectOnScreen, mScreenRect)
-            && Rect.intersects(mContentRectOnScreen, mViewRectOnScreen);
+        return intersectsClosed(mContentRectOnScreen, mScreenRect)
+            && intersectsClosed(mContentRectOnScreen, mViewRectOnScreen);
+    }
+
+    /*
+     * Same as Rect.intersects, but includes cases where the rectangles touch.
+    */
+    private static boolean intersectsClosed(Rect a, Rect b) {
+         return a.left <= b.right && b.left <= a.right
+                 && a.top <= b.bottom && b.top <= a.bottom;
     }
 
     @Override
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index c97de5d..2164eec 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -679,17 +679,31 @@
         @Override
         public int getWidth() {
             throwISEIfImageIsInvalid();
-            mWidth = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getWidth() :
-                    nativeGetWidth(mFormat);
-            return mWidth;
+            int width;
+            switch(getFormat()) {
+                case ImageFormat.JPEG:
+                case ImageFormat.DEPTH_POINT_CLOUD:
+                    width = ImageReader.this.getWidth();
+                    break;
+                default:
+                    width = nativeGetWidth(mFormat);
+            }
+            return width;
         }
 
         @Override
         public int getHeight() {
             throwISEIfImageIsInvalid();
-            mHeight = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getHeight() :
-                    nativeGetHeight(mFormat);
-            return mHeight;
+            int height;
+            switch(getFormat()) {
+                case ImageFormat.JPEG:
+                case ImageFormat.DEPTH_POINT_CLOUD:
+                    height = ImageReader.this.getHeight();
+                    break;
+                default:
+                    height = nativeGetHeight(mFormat);
+            }
+            return height;
         }
 
         @Override
@@ -826,8 +840,6 @@
         private long mTimestamp;
 
         private SurfacePlane[] mPlanes;
-        private int mHeight = -1;
-        private int mWidth = -1;
         private int mFormat = ImageFormat.UNKNOWN;
         // If this image is detached from the ImageReader.
         private AtomicBoolean mIsDetached = new AtomicBoolean(false);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index d3f33ab..50234b2 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -16,7 +16,6 @@
 package com.android.systemui.tuner;
 
 import android.app.ActivityManager;
-import android.app.AlertDialog;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -25,10 +24,12 @@
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.ArrayMap;
 
@@ -169,6 +170,7 @@
 
     public static final void showResetRequest(final Context context, final Runnable onDisabled) {
         SystemUIDialog dialog = new SystemUIDialog(context);
+        dialog.setShowForAllUsers(true);
         dialog.setMessage(R.string.remove_from_settings_prompt);
         dialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel),
                 (OnClickListener) null);
@@ -192,7 +194,7 @@
     }
 
     public static final void setTunerEnabled(Context context, boolean enabled) {
-        context.getPackageManager().setComponentEnabledSetting(
+        userContext(context).getPackageManager().setComponentEnabledSetting(
                 new ComponentName(context, TunerActivity.class),
                 enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                         : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
@@ -200,11 +202,20 @@
     }
 
     public static final boolean isTunerEnabled(Context context) {
-        return context.getPackageManager().getComponentEnabledSetting(
+        return userContext(context).getPackageManager().getComponentEnabledSetting(
                 new ComponentName(context, TunerActivity.class))
                 == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
     }
 
+    private static Context userContext(Context context) {
+        try {
+            return context.createPackageContextAsUser(context.getPackageName(), 0,
+                    new UserHandle(ActivityManager.getCurrentUser()));
+        } catch (NameNotFoundException e) {
+            return context;
+        }
+    }
+
     private class Observer extends ContentObserver {
         public Observer() {
             super(new Handler(Looper.getMainLooper()));
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index c0d0d13..5c1878e 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1774,7 +1774,7 @@
         maybeRefreshTrustedTime();
         synchronized (mRulesLock) {
             mRestrictBackground = restrictBackground;
-            updateRulesForGlobalChangeLocked(false);
+            updateRulesForGlobalChangeLocked(true);
             updateNotificationsLocked();
             writePolicyLocked();
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6a4ae3d..21e256e8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -481,12 +481,21 @@
         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
 
     /**
-     * Tracks new system packages [receiving in an OTA] that we expect to
+     * Tracks new system packages [received in an OTA] that we expect to
      * find updated user-installed versions. Keys are package name, values
      * are package location.
      */
     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
 
+    /**
+     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
+     */
+    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
+    /**
+     * Whether or not system app permissions should be promoted from install to runtime.
+     */
+    boolean mPromoteSystemApps;
+
     final Settings mSettings;
     boolean mRestoredSettings;
 
@@ -2028,6 +2037,24 @@
                 }
             }
 
+            final VersionInfo ver = mSettings.getInternalVersion();
+            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
+            // when upgrading from pre-M, promote system app permissions from install to runtime
+            mPromoteSystemApps =
+                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
+
+            // save off the names of pre-existing system packages prior to scanning; we don't
+            // want to automatically grant runtime permissions for new system apps
+            if (mPromoteSystemApps) {
+                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
+                while (pkgSettingIter.hasNext()) {
+                    PackageSetting ps = pkgSettingIter.next();
+                    if (isSystemApp(ps)) {
+                        mExistingSystemPackages.add(ps.name);
+                    }
+                }
+            }
+
             // Collect vendor overlay packages.
             // (Do this before scanning any apps.)
             // For security and version matching reason, only consider
@@ -2247,8 +2274,6 @@
             // cases get permissions that the user didn't initially explicitly
             // allow...  it would be nice to have some better way to handle
             // this situation.
-            final VersionInfo ver = mSettings.getInternalVersion();
-
             int updateFlags = UPDATE_PERMISSIONS_ALL;
             if (ver.sdkVersion != mSdkVersion) {
                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
@@ -2257,6 +2282,9 @@
             }
             updatePermissionsLPw(null, null, updateFlags);
             ver.sdkVersion = mSdkVersion;
+            // clear only after permissions have been updated
+            mExistingSystemPackages.clear();
+            mPromoteSystemApps = false;
 
             // If this is the first boot, and it is a normal boot, then
             // we need to initialize the default preferred apps.
@@ -2268,7 +2296,6 @@
 
             // If this is first boot after an OTA, and a normal boot, then
             // we need to clear code cache directories.
-            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
             if (mIsUpgrade && !onlyCore) {
                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
@@ -8356,6 +8383,13 @@
                     } else if (origPermissions.hasInstallPermission(bp.name)) {
                         // For legacy apps that became modern, install becomes runtime.
                         grant = GRANT_UPGRADE;
+                    } else if (mPromoteSystemApps
+                            && isSystemApp(ps)
+                            && mExistingSystemPackages.contains(ps.name)) {
+                        // For legacy system apps, install becomes runtime.
+                        // We cannot check hasInstallPermission() for system apps since those
+                        // permissions were granted implicitly and not persisted pre-M.
+                        grant = GRANT_UPGRADE;
                     } else {
                         // For modern apps keep runtime permissions unchanged.
                         grant = GRANT_RUNTIME;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index c4ff277..489bcdb 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3617,7 +3617,8 @@
                         // We currently want to hide the navigation UI.
                         mNavigationBarController.setBarShowingLw(false);
                     }
-                    if (navVisible && !navTranslucent && !mNavigationBar.isAnimatingLw()
+                    if (navVisible && !navTranslucent && !navAllowedHidden
+                            && !mNavigationBar.isAnimatingLw()
                             && !mNavigationBarController.wasRecentlyTranslucent()) {
                         // If the nav bar is currently requested to be visible,
                         // and not in the process of animating on or off, then
@@ -5492,10 +5493,6 @@
         // may happen in a future call to goToSleep.
         synchronized (mLock) {
             mAwake = true;
-            if (mKeyguardDelegate != null) {
-                mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
-                mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);
-            }
 
             updateWakeGestureListenerLp();
             updateOrientationListenerLp();
@@ -5585,6 +5582,8 @@
             mScreenOnListener = screenOnListener;
 
             if (mKeyguardDelegate != null) {
+                mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
+                mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);
                 mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
             } else {
                 if (DEBUG_WAKEUP) Slog.d(TAG,
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 147efdd..c71b48f 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -465,6 +465,9 @@
             pw.println(prefix + "mLastFilteredX=" + mLastFilteredX);
             pw.println(prefix + "mLastFilteredY=" + mLastFilteredY);
             pw.println(prefix + "mLastFilteredZ=" + mLastFilteredZ);
+            final long delta = SystemClock.elapsedRealtimeNanos() - mLastFilteredTimestampNanos;
+            pw.println(prefix + "mLastFilteredTimestampNanos=" + mLastFilteredTimestampNanos
+                    + " (" + (delta * 0.000001f) + "ms ago)");
             pw.println(prefix + "mTiltHistory={last: " + getLastTiltLocked() + "}");
             pw.println(prefix + "mFlat=" + mFlat);
             pw.println(prefix + "mSwinging=" + mSwinging);