Merge "TIF: Fix the Singapore content ratings" into lmp-dev
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index f31800d..3760b96 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -19,6 +19,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.content.Intent;
+import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.RectF;
 import android.graphics.drawable.ColorDrawable;
@@ -222,10 +223,7 @@
             delayCancel();
             moveSharedElementsToOverlay();
             if (getDecor().getBackground() == null) {
-                ColorDrawable black = new ColorDrawable(0xFF000000);
-                black.setAlpha(0);
-                getWindow().setBackgroundDrawable(black);
-                black.setAlpha(255);
+                getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
             }
             ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
                     mAllSharedElementNames, resultCode, data);
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 7834ef8..4873479 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -93,6 +93,10 @@
 
 inline int getExtraVertexNumber(const Vector2& vector1, const Vector2& vector2,
         float divisor) {
+    // When there is no distance difference, there is no need for extra vertices.
+    if (vector1.lengthSquared() == 0 || vector2.lengthSquared() == 0) {
+        return 0;
+    }
     // The formula is :
     // extraNumber = floor(acos(dot(n1, n2)) / (M_PI / EXTRA_VERTEX_PER_PI))
     // The value ranges for each step are:
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index 00183bb..46b8871 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -416,23 +416,22 @@
      * Loads the user-displayed icon for this TV input.
      *
      * @param context Supplies a {@link Context} used to load the icon.
-     * @return a Drawable containing the TV input's icon. If the TV input does not have
-     *         an icon, application icon is returned. If it's unavailable too, system default is
-     *         returned.
+     * @return a Drawable containing the TV input's icon. If the TV input does not have an icon,
+     *         application's icon is returned. If it's unavailable too, {@code null} is returned.
      */
     public Drawable loadIcon(Context context) {
         if (mIconUri == null) {
-            return loadDefaultIcon(context);
+            return loadServiceIcon(context);
         }
         try (InputStream is = context.getContentResolver().openInputStream(mIconUri)) {
             Drawable drawable = Drawable.createFromStream(is, null);
             if (drawable == null) {
-                return loadDefaultIcon(context);
+                return loadServiceIcon(context);
             }
             return drawable;
         } catch (IOException e) {
             Log.w(TAG, "Loading the default icon due to a failure on loading " + mIconUri, e);
-            return loadDefaultIcon(context);
+            return loadServiceIcon(context);
         }
     }
 
@@ -486,7 +485,11 @@
         dest.writeByte(mIsConnectedToHdmiSwitch ? (byte) 1 : 0);
     }
 
-    private Drawable loadDefaultIcon(Context context) {
+    private Drawable loadServiceIcon(Context context) {
+        if (mService.serviceInfo.icon == 0
+                && mService.serviceInfo.applicationInfo.icon == 0) {
+            return null;
+        }
         return mService.serviceInfo.loadIcon(context.getPackageManager());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 3f631f7..ce29407 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -365,6 +365,24 @@
                     Notification n = sbn.getNotification();
                     boolean isUpdate = mNotificationData.get(sbn.getKey()) != null
                             || isHeadsUp(sbn.getKey());
+
+                    // Ignore children of notifications that have a summary, since we're not
+                    // going to show them anyway. This is true also when the summary is canceled,
+                    // because children are automatically canceled by NoMan in that case.
+                    if (n.isGroupChild() &&
+                            mNotificationData.isGroupWithSummary(sbn.getGroupKey())) {
+                        if (DEBUG) {
+                            Log.d(TAG, "Ignoring group child due to existing summary: " + sbn);
+                        }
+
+                        // Remove existing notification to avoid stale data.
+                        if (isUpdate) {
+                            removeNotification(sbn.getKey(), rankingMap);
+                        } else {
+                            mNotificationData.updateRanking(rankingMap);
+                        }
+                        return;
+                    }
                     if (isUpdate) {
                         updateNotification(sbn, rankingMap);
                     } else {
@@ -736,15 +754,20 @@
             public boolean onLongPress(View v, int x, int y) {
                 dismissPopups();
 
-                if (v.getWindowToken() == null) return false;
+                if (v.getWindowToken() == null) {
+                    Log.e(TAG, "Trying to show notification guts, but not attached to window");
+                    return false;
+                }
 
                 // Assume we are a status_bar_notification_row
                 final NotificationGuts guts = (NotificationGuts) v.findViewById(
                         R.id.notification_guts);
-                if (guts == null) return false;
 
                 // Already showing?
-                if (guts.getVisibility() == View.VISIBLE) return false;
+                if (guts.getVisibility() == View.VISIBLE) {
+                    Log.e(TAG, "Trying to show notification guts, but already visible");
+                    return false;
+                }
 
                 guts.setVisibility(View.VISIBLE);
                 final double horz = Math.max(guts.getWidth() - x, x);
@@ -768,6 +791,8 @@
             final NotificationGuts v = mNotificationGutsExposed;
             mNotificationGutsExposed = null;
 
+            if (v.getWindowToken() == null) return;
+
             final int x = (v.getLeft() + v.getRight()) / 2;
             final int y = (v.getTop() + v.getActualHeight() / 2);
             final Animator a = ViewAnimationUtils.createCircularReveal(v,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 7e37336..454041c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -89,6 +89,7 @@
 
     private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
     private final ArrayList<Entry> mSortedAndFiltered = new ArrayList<>();
+    private ArraySet<String> mGroupsWithSummaries = new ArraySet<>();
 
     private RankingMap mRankingMap;
     private final Ranking mTmpRanking = new Ranking();
@@ -183,8 +184,8 @@
     // anything changed, and this class should call back the UI so it updates itself.
     public void filterAndSort() {
         mSortedAndFiltered.clear();
+        mGroupsWithSummaries.clear();
 
-        ArraySet<String> groupsWithSummaries = null;
         final int N = mEntries.size();
         for (int i = 0; i < N; i++) {
             Entry entry = mEntries.valueAt(i);
@@ -195,22 +196,19 @@
             }
 
             if (sbn.getNotification().isGroupSummary()) {
-                if (groupsWithSummaries == null) {
-                    groupsWithSummaries = new ArraySet<>();
-                }
-                groupsWithSummaries.add(sbn.getGroupKey());
+                mGroupsWithSummaries.add(sbn.getGroupKey());
             }
             mSortedAndFiltered.add(entry);
         }
 
         // Second pass: Filter out group children with summary.
-        if (groupsWithSummaries != null) {
+        if (!mGroupsWithSummaries.isEmpty()) {
             final int M = mSortedAndFiltered.size();
             for (int i = M - 1; i >= 0; i--) {
                 Entry ent = mSortedAndFiltered.get(i);
                 StatusBarNotification sbn = ent.notification;
                 if (sbn.getNotification().isGroupChild() &&
-                        groupsWithSummaries.contains(sbn.getGroupKey())) {
+                        mGroupsWithSummaries.contains(sbn.getGroupKey())) {
                     mSortedAndFiltered.remove(i);
                 }
             }
@@ -219,6 +217,10 @@
         Collections.sort(mSortedAndFiltered, mRankingComparator);
     }
 
+    public boolean isGroupWithSummary(String groupKey) {
+        return mGroupsWithSummaries.contains(groupKey);
+    }
+
     private boolean shouldFilterOut(StatusBarNotification sbn) {
         if (!(mEnvironment.isDeviceProvisioned() ||
                 showNotificationEvenIfUnprovisioned(sbn))) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 3bb403d..0fb2192 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -87,7 +87,7 @@
     private final NavTransitionListener mTransitionListener = new NavTransitionListener();
 
     private OnVerticalChangedListener mOnVerticalChangedListener;
-    private boolean mIsLtr;
+    private boolean mIsLayoutRtl;
 
     private class NavTransitionListener implements TransitionListener {
         private boolean mBackTransitioning;
@@ -394,7 +394,7 @@
 
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
-        updateLTROrder();
+        updateRTLOrder();
     }
 
     public boolean isVertical() {
@@ -460,17 +460,17 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        updateLTROrder();
+        updateRTLOrder();
     }
 
     /**
      * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
      * have to do it manually
      */
-    private void updateLTROrder() {
-        boolean isLtr = getResources().getConfiguration()
+    private void updateRTLOrder() {
+        boolean isLayoutRtl = getResources().getConfiguration()
                 .getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-        if (mIsLtr != isLtr) {
+        if (mIsLayoutRtl != isLayoutRtl) {
 
             // We swap all children of the 90 and 270 degree layouts, since they are vertical
             View rotation90 = mRotatedViews[Surface.ROTATION_90];
@@ -480,7 +480,7 @@
             if (rotation90 != rotation270) {
                 swapChildrenOrderIfVertical(rotation270.findViewById(R.id.nav_buttons));
             }
-            mIsLtr = isLtr;
+            mIsLayoutRtl = isLayoutRtl;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index e818d23..6127811 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -720,6 +720,8 @@
         abortAnimations();
         if (mTracking) {
             onTrackingStopped(true /* expands */); // The panel is expanded after this call.
+        }
+        if (mExpanding) {
             notifyExpandingFinished();
         }
         setVisibility(VISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 82e7f5d..148b00c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -580,7 +580,7 @@
             }
             float childTop = slidingChild.getTranslationY();
             float top = childTop + slidingChild.getClipTopAmount();
-            float bottom = top + slidingChild.getActualHeight();
+            float bottom = childTop + slidingChild.getActualHeight();
 
             // Allow the full width of this view to prevent gesture conflict on Keyguard (phone and
             // camera affordance).
@@ -1530,7 +1530,7 @@
                 return position;
             }
             if (child.getVisibility() != View.GONE) {
-                position += child.getHeight();
+                position += getIntrinsicHeight(child);
                 if (i < getChildCount()-1) {
                     position += mPaddingBetweenElements;
                 }
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 92f5170..adfbb16 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -116,7 +116,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             // Update keystore settings for profiles which use the same password as their parent
-            if (Intent.ACTION_USER_STARTED.equals(intent.getAction())) {
+            if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
                 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                 final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
                 final UserInfo parentInfo = um.getProfileParent(userHandle);
@@ -319,17 +319,18 @@
         String dataSystemDirectory =
                 android.os.Environment.getDataDirectory().getAbsolutePath() +
                 SYSTEM_DIRECTORY;
+        userId = getUserParentOrSelfId(userId);
         if (userId == 0) {
             // Leave it in the same place for user 0
             return dataSystemDirectory + LOCK_PATTERN_FILE;
         } else {
-            userId = getUserParentOrSelfId(userId);
             return  new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE)
                     .getAbsolutePath();
         }
     }
 
     private String getLockPasswordFilename(int userId) {
+        userId = getUserParentOrSelfId(userId);
         String dataSystemDirectory =
                 android.os.Environment.getDataDirectory().getAbsolutePath() +
                 SYSTEM_DIRECTORY;
@@ -337,7 +338,6 @@
             // Leave it in the same place for user 0
             return dataSystemDirectory + LOCK_PASSWORD_FILE;
         } else {
-            userId = getUserParentOrSelfId(userId);
             return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE)
                     .getAbsolutePath();
         }
@@ -510,13 +510,18 @@
 
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         try {
-            File file = new File(getLockPasswordFilename(userId));
-            if (file.exists()) {
-                file.delete();
-            }
-            file = new File(getLockPatternFilename(userId));
-            if (file.exists()) {
-                file.delete();
+            final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+            final UserInfo parentInfo = um.getProfileParent(userId);
+            if (parentInfo == null) {
+                // This user owns its lock settings files - safe to delete them
+                File file = new File(getLockPasswordFilename(userId));
+                if (file.exists()) {
+                    file.delete();
+                }
+                file = new File(getLockPatternFilename(userId));
+                if (file.exists()) {
+                    file.delete();
+                }
             }
 
             db.beginTransaction();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c2c86ff..51a40d4 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -10272,13 +10272,13 @@
                 if (r == null) {
                     return false;
                 }
-                if (r.changeWindowTranslucency(true)) {
-                    mWindowManager.setAppFullscreen(token, true);
+                final boolean translucentChanged = r.changeWindowTranslucency(true);
+                if (translucentChanged) {
                     r.task.stack.releaseBackgroundResources();
                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
-                    return true;
                 }
-                return false;
+                mWindowManager.setAppFullscreen(token, true);
+                return translucentChanged;
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -10299,15 +10299,13 @@
                     ActivityRecord under = r.task.mActivities.get(index - 1);
                     under.returningOptions = options;
                 }
-                if (r.changeWindowTranslucency(false)) {
+                final boolean translucentChanged = r.changeWindowTranslucency(false);
+                if (translucentChanged) {
                     r.task.stack.convertToTranslucent(r);
-                    mWindowManager.setAppFullscreen(token, false);
                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
-                    return true;
-                } else {
-                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
-                    return false;
                 }
+                mWindowManager.setAppFullscreen(token, false);
+                return translucentChanged;
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c70cb22..0a01247 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4306,11 +4306,7 @@
         AppWindowToken atoken = findAppWindowToken(token);
         if (atoken != null) {
             atoken.appFullscreen = toOpaque;
-            // When making translucent, wait until windows below have been drawn.
-            if (toOpaque) {
-                // Making opaque so do it now.
-                setWindowOpaque(token, true);
-            }
+            setWindowOpaque(token, toOpaque);
             requestTraversal();
         }
     }