diff options
30 files changed, 191 insertions, 129 deletions
diff --git a/api/current.txt b/api/current.txt index c960ad92f7c7..cc3b0852f260 100644 --- a/api/current.txt +++ b/api/current.txt @@ -47464,7 +47464,7 @@ package android.widget { method public void setChar(int, java.lang.String, char); method public void setCharSequence(int, java.lang.String, java.lang.CharSequence); method public void setChronometer(int, long, java.lang.String, boolean); - method public void setChronometerCountsDown(int, boolean); + method public void setChronometerCountDown(int, boolean); method public void setContentDescription(int, java.lang.CharSequence); method public void setDisplayedChild(int, int); method public void setDouble(int, java.lang.String, double); diff --git a/api/system-current.txt b/api/system-current.txt index 04f522d9e893..7a7167295e63 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -50769,7 +50769,7 @@ package android.widget { method public void setChar(int, java.lang.String, char); method public void setCharSequence(int, java.lang.String, java.lang.CharSequence); method public void setChronometer(int, long, java.lang.String, boolean); - method public void setChronometerCountsDown(int, boolean); + method public void setChronometerCountDown(int, boolean); method public void setContentDescription(int, java.lang.CharSequence); method public void setDisplayedChild(int, int); method public void setDouble(int, java.lang.String, double); diff --git a/api/test-current.txt b/api/test-current.txt index abe91bc3e603..39d69f3011f3 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -47541,7 +47541,7 @@ package android.widget { method public void setChar(int, java.lang.String, char); method public void setCharSequence(int, java.lang.String, java.lang.CharSequence); method public void setChronometer(int, long, java.lang.String, boolean); - method public void setChronometerCountsDown(int, boolean); + method public void setChronometerCountDown(int, boolean); method public void setContentDescription(int, java.lang.CharSequence); method public void setDisplayedChild(int, int); method public void setDouble(int, java.lang.String, double); diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index e4fff9dc8a8c..02dcc5c7e3bd 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -33,7 +33,6 @@ import android.util.Log; import libcore.util.ZoneInfoDB; import java.io.IOException; -import java.lang.ref.WeakReference; import java.util.WeakHashMap; /** @@ -245,12 +244,7 @@ public class AlarmManager { // Tracking of the OnAlarmListener -> wrapper mapping, for cancel() support. // Access is synchronized on the AlarmManager class object. - // - // These are weak references so that we don't leak listener references if, for - // example, the pending-alarm messages are posted to a HandlerThread that is - // disposed of prior to alarm delivery. The underlying messages will be GC'd - // but this static reference would still persist, orphaned, never deallocated. - private static WeakHashMap<OnAlarmListener, WeakReference<ListenerWrapper>> sWrappers; + private static WeakHashMap<OnAlarmListener, ListenerWrapper> sWrappers; /** * package private on purpose @@ -637,16 +631,14 @@ public class AlarmManager { if (listener != null) { synchronized (AlarmManager.class) { if (sWrappers == null) { - sWrappers = new WeakHashMap<OnAlarmListener, WeakReference<ListenerWrapper>>(); + sWrappers = new WeakHashMap<OnAlarmListener, ListenerWrapper>(); } - WeakReference<ListenerWrapper> wrapperRef = sWrappers.get(listener); - // no existing wrapper *or* we've lost our weak ref to it => build a new one - if (wrapperRef == null || - (recipientWrapper = wrapperRef.get()) == null) { + recipientWrapper = sWrappers.get(listener); + // no existing wrapper => build a new one + if (recipientWrapper == null) { recipientWrapper = new ListenerWrapper(listener); - wrapperRef = new WeakReference<ListenerWrapper>(recipientWrapper); - sWrappers.put(listener, wrapperRef); + sWrappers.put(listener, recipientWrapper); } } @@ -906,11 +898,7 @@ public class AlarmManager { ListenerWrapper wrapper = null; synchronized (AlarmManager.class) { if (sWrappers != null) { - final WeakReference<ListenerWrapper> wrapperRef; - wrapperRef = sWrappers.get(listener); - if (wrapperRef != null) { - wrapper = wrapperRef.get(); - } + wrapper = sWrappers.get(listener); } } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 400a313979d8..39f8e190aeab 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -25,7 +25,6 @@ import android.annotation.SystemApi; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.ColorStateList; @@ -186,6 +185,11 @@ public class Notification implements Parcelable public long when; /** + * The creation time of the notification + */ + private long creationTime; + + /** * The resource id of a drawable to use as the icon in the status bar. * * @deprecated Use {@link Builder#setSmallIcon(Icon)} instead. @@ -1480,6 +1484,7 @@ public class Notification implements Parcelable public Notification() { this.when = System.currentTimeMillis(); + this.creationTime = System.currentTimeMillis(); this.priority = PRIORITY_DEFAULT; } @@ -1517,6 +1522,7 @@ public class Notification implements Parcelable this.icon = icon; this.tickerText = tickerText; this.when = when; + this.creationTime = System.currentTimeMillis(); } /** @@ -1527,6 +1533,7 @@ public class Notification implements Parcelable int version = parcel.readInt(); when = parcel.readLong(); + creationTime = parcel.readLong(); if (parcel.readInt() != 0) { mSmallIcon = Icon.CREATOR.createFromParcel(parcel); if (mSmallIcon.getType() == Icon.TYPE_RESOURCE) { @@ -1615,6 +1622,7 @@ public class Notification implements Parcelable */ public void cloneInto(Notification that, boolean heavy) { that.when = this.when; + that.creationTime = this.creationTime; that.mSmallIcon = this.mSmallIcon; that.number = this.number; @@ -1795,6 +1803,7 @@ public class Notification implements Parcelable parcel.writeInt(1); parcel.writeLong(when); + parcel.writeLong(creationTime); if (mSmallIcon == null && icon != 0) { // you snuck an icon in here without using the builder; let's try to keep it mSmallIcon = Icon.createWithResource("", icon); @@ -3130,6 +3139,7 @@ public class Notification implements Parcelable contentView.setViewVisibility(R.id.header_text, View.GONE); contentView.setViewVisibility(R.id.header_text_divider, View.GONE); contentView.setViewVisibility(R.id.time_divider, View.GONE); + contentView.setViewVisibility(R.id.time, View.GONE); contentView.setImageViewIcon(R.id.profile_badge, null); contentView.setViewVisibility(R.id.profile_badge, View.GONE); } @@ -3260,11 +3270,15 @@ public class Notification implements Parcelable mN.when + (SystemClock.elapsedRealtime() - System.currentTimeMillis())); contentView.setBoolean(R.id.chronometer, "setStarted", true); boolean countsDown = mN.extras.getBoolean(EXTRA_CHRONOMETER_COUNTS_DOWN); - contentView.setChronometerCountsDown(R.id.chronometer, countsDown); + contentView.setChronometerCountDown(R.id.chronometer, countsDown); } else { contentView.setViewVisibility(R.id.time, View.VISIBLE); contentView.setLong(R.id.time, "setTime", mN.when); } + } else { + // We still want a time to be set but gone, such that we can show and hide it + // on demand in case it's a child notification without anything in the header + contentView.setLong(R.id.time, "setTime", mN.when != 0 ? mN.when : mN.creationTime); } } @@ -3332,7 +3346,7 @@ public class Notification implements Parcelable * otherwise */ private boolean showsTimeOrChronometer() { - return mN.when != 0 && mN.extras.getBoolean(EXTRA_SHOW_WHEN); + return mN.showsTimeOrChronometer(); } private void resetStandardTemplateWithActions(RemoteViews big) { @@ -3694,6 +3708,8 @@ public class Notification implements Parcelable mN.extras = getAllExtras(); } + mN.creationTime = System.currentTimeMillis(); + // lazy stuff from mContext; see comment in Builder(Context, Notification) Notification.addFieldsFromContext(mContext, mN); @@ -3827,6 +3843,15 @@ public class Notification implements Parcelable } /** + * @return true if the notification will show the time or the chronometer; false + * otherwise + * @hide + */ + public boolean showsTimeOrChronometer() { + return when != 0 && extras.getBoolean(EXTRA_SHOW_WHEN); + } + + /** * An object that can apply a rich notification style to a {@link Notification.Builder} * object. */ diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 996ccba3c1b7..c8bf4d65418c 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -3078,10 +3078,6 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED"; - /** @hide */ - public static final String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = - "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED"; - /** * Broadcast sent to the primary user when an associated managed profile has become available. * Currently this includes when the user disables quiet mode for the profile. Carries an extra diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java index 39eba7d3d706..d2ee86622e08 100644 --- a/core/java/android/widget/DateTimeView.java +++ b/core/java/android/widget/DateTimeView.java @@ -131,8 +131,18 @@ public class DateTimeView extends TextView { update(); } + @Override + @android.view.RemotableViewMethod + public void setVisibility(@Visibility int visibility) { + boolean gotVisible = visibility != GONE && getVisibility() == GONE; + super.setVisibility(visibility); + if (gotVisible) { + update(); + } + } + void update() { - if (mTime == null) { + if (mTime == null || getVisibility() == GONE) { return; } if (mShowRelativeTime) { diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index a9b7f4e97e7c..6dc5ff7c427a 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -2600,7 +2600,7 @@ public class RemoteViews implements Parcelable, Filter { * simply display the timer value. * @param started True if you want the clock to be started, false if not. * - * @see #setChronometerCountsDown(int, boolean) + * @see #setChronometerCountDown(int, boolean) */ public void setChronometer(int viewId, long base, String format, boolean started) { setLong(viewId, "setBase", base); @@ -2616,7 +2616,7 @@ public class RemoteViews implements Parcelable, Filter { * @param isCountDown True if you want the chronometer to count down to base instead of * counting up. */ - public void setChronometerCountsDown(int viewId, boolean isCountDown) { + public void setChronometerCountDown(int viewId, boolean isCountDown) { setBoolean(viewId, "setCountDown", isCountDown); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index a59809699be2..eb0c7424e3f5 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -347,10 +347,6 @@ <protected-broadcast android:name="android.app.action.SYSTEM_UPDATE_POLICY_CHANGED" /> <protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" /> - <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED" /> - <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABLE" /> - <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNAVAILABLE" /> - <!-- Added in N --> <protected-broadcast android:name="android.intent.action.ANR" /> <protected-broadcast android:name="android.intent.action.CALL" /> diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml index 992e88e22ad9..d16dcc6b906c 100644 --- a/core/res/res/layout/notification_template_header.xml +++ b/core/res/res/layout/notification_template_header.xml @@ -69,15 +69,17 @@ android:text="@string/notification_header_divider_symbol" android:singleLine="true" android:visibility="gone"/> - <ViewStub + <DateTimeView android:id="@+id/time" + android:textAppearance="@style/TextAppearance.Material.Notification.Time" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_gravity="center" android:layout_marginStart="2dp" android:layout_marginEnd="2dp" - android:layout="@layout/notification_template_part_time" - android:visibility="gone" - /> + android:showRelative="true" + android:singleLine="true" + android:visibility="gone" /> <ViewStub android:id="@+id/chronometer" android:layout_width="wrap_content" diff --git a/core/res/res/layout/notification_template_part_time.xml b/core/res/res/layout/notification_template_part_time.xml deleted file mode 100644 index e53f37807df9..000000000000 --- a/core/res/res/layout/notification_template_part_time.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 The Android Open 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. ---> - -<DateTimeView android:id="@+id/time" xmlns:android="http://schemas.android.com/apk/res/android" - android:textAppearance="@style/TextAppearance.Material.Notification.Time" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:layout_marginEnd="4dp" - android:layout_weight="0" - android:showRelative="true" - android:singleLine="true" - /> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 6e9de231e48e..2806729b835a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -1346,7 +1346,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { expandButton.setVisibility(VISIBLE); mNotificationHeader.setOnClickListener(mExpandClickListener); mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(), - mNotificationHeader); + mNotificationHeader, this); addView(mNotificationHeader, indexOfChild(mChildrenContainer) + 1); mTranslateableViews.add(mNotificationHeader); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index 491ffde8071f..83f68e81bca7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -307,7 +307,8 @@ public class NotificationContentView extends FrameLayout { addView(child); mContractedChild = child; mContractedChild.addOnLayoutChangeListener(mLayoutUpdater); - mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child); + mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child, + mContainingNotification); selectLayout(false /* animate */, true /* force */); mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */); } @@ -321,7 +322,8 @@ public class NotificationContentView extends FrameLayout { addView(child); mExpandedChild = child; mExpandedChild.addOnLayoutChangeListener(mLayoutUpdater); - mExpandedWrapper = NotificationViewWrapper.wrap(getContext(), child); + mExpandedWrapper = NotificationViewWrapper.wrap(getContext(), child, + mContainingNotification); selectLayout(false /* animate */, true /* force */); } @@ -334,7 +336,8 @@ public class NotificationContentView extends FrameLayout { addView(child); mHeadsUpChild = child; mHeadsUpChild.addOnLayoutChangeListener(mLayoutUpdater); - mHeadsUpWrapper = NotificationViewWrapper.wrap(getContext(), child); + mHeadsUpWrapper = NotificationViewWrapper.wrap(getContext(), child, + mContainingNotification); selectLayout(false /* animate */, true /* force */); } @@ -834,10 +837,14 @@ public class NotificationContentView extends FrameLayout { public void updateExpandButtons(boolean expandable) { mExpandable = expandable; // if the expanded child has the same height as the collapsed one we hide it. - if (mExpandedChild != null && mExpandedChild.getHeight() != 0 && - ((mIsHeadsUp && mExpandedChild.getHeight() == mHeadsUpChild.getHeight()) || - (!mIsHeadsUp && mExpandedChild.getHeight() == mContractedChild.getHeight()))) { - expandable = false; + if (mExpandedChild != null && mExpandedChild.getHeight() != 0) { + if ((!mIsHeadsUp || mHeadsUpChild == null)) { + if (mExpandedChild.getHeight() == mContractedChild.getHeight()) { + expandable = false; + } + } else if (mExpandedChild.getHeight() == mHeadsUpChild.getHeight()) { + expandable = false; + } } if (mExpandedChild != null) { mExpandedWrapper.updateExpandability(expandable, mExpandClickListener); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java index 06d79a7f9124..3363993dd289 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java @@ -65,12 +65,7 @@ public class NotificationHeaderUtil { ImageView expand = (ImageView) view.findViewById( com.android.internal.R.id.expand_button); applyToChild(icon, apply, header.getOriginalIconColor()); - int color = header.getOriginalNotificationColor(); - if (color == Notification.COLOR_DEFAULT) { - color = view.getContext().getColor( - com.android.internal.R.color.notification_icon_default_color); - } - applyToChild(expand, apply, color); + applyToChild(expand, apply, header.getOriginalNotificationColor()); } private void applyToChild(View view, boolean shouldApply, int originalColor) { @@ -116,7 +111,7 @@ public class NotificationHeaderUtil { @Override public boolean compare(View parent, View child, Object parentData, Object childData) { - return parent.getVisibility() == View.VISIBLE; + return parent.getVisibility() != View.GONE; } @Override @@ -161,11 +156,11 @@ public class NotificationHeaderUtil { mComparators.get(compI).apply(row); } // We need to sanitize the dividers since they might be off-balance now - sanitizeDividers(row); + sanitizeHeaderViews(row); } } - private void sanitizeDividers(ExpandableNotificationRow row) { + private void sanitizeHeaderViews(ExpandableNotificationRow row) { if (row.isSummaryWithChildren()) { sanitizeHeader(row.getNotificationHeader()); return; @@ -188,9 +183,26 @@ public class NotificationHeaderUtil { if (rowHeader == null) { return; } + final int childCount = rowHeader.getChildCount(); + View time = rowHeader.findViewById(com.android.internal.R.id.time); + boolean hasVisibleText = false; + for (int i = 1; i < childCount - 1 ; i++) { + View child = rowHeader.getChildAt(i); + if (child instanceof TextView + && child.getVisibility() != View.GONE + && !mDividers.contains(Integer.valueOf(child.getId())) + && child != time) { + hasVisibleText = true; + break; + } + } + // in case no view is visible we make sure the time is visible + int timeVisibility = !hasVisibleText + || mRow.getStatusBarNotification().getNotification().showsTimeOrChronometer() + ? View.VISIBLE : View.GONE; + time.setVisibility(timeVisibility); View left = null; View right; - final int childCount = rowHeader.getChildCount(); for (int i = 1; i < childCount - 1 ; i++) { View child = rowHeader.getChildAt(i); if (mDividers.contains(Integer.valueOf(child.getId()))) { @@ -202,14 +214,14 @@ public class NotificationHeaderUtil { // A divider was found, this needs to be hidden i--; break; - } else if (right.getVisibility() == View.VISIBLE) { + } else if (right.getVisibility() != View.GONE && right instanceof TextView) { visible = left != null; left = right; break; } } child.setVisibility(visible ? View.VISIBLE : View.GONE); - } else if (child.getVisibility() == View.VISIBLE) { + } else if (child.getVisibility() != View.GONE && child instanceof TextView) { left = child; } } @@ -219,7 +231,7 @@ public class NotificationHeaderUtil { for (int compI = 0; compI < mComparators.size(); compI++) { mComparators.get(compI).apply(row, true /* reset */); } - sanitizeDividers(row); + sanitizeHeaderViews(row); } private static class HeaderProcessor { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index 988d537f6c2c..2b59c68a44b8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -295,6 +295,14 @@ public class SignalClusterView return; } // Clear out all old subIds. + for (PhoneState state : mPhoneStates) { + if (state.mMobile != null) { + state.maybeStopAnimatableDrawable(state.mMobile); + } + if (state.mMobileDark != null) { + state.maybeStopAnimatableDrawable(state.mMobileDark); + } + } mPhoneStates.clear(); if (mMobileSignalGroup != null) { mMobileSignalGroup.removeAllViews(); @@ -391,6 +399,11 @@ public class SignalClusterView state.mMobile.setImageDrawable(null); state.mLastMobileStrengthId = -1; } + if (state.mMobileDark != null) { + state.maybeStopAnimatableDrawable(state.mMobileDark); + state.mMobileDark.setImageDrawable(null); + state.mLastMobileStrengthId = -1; + } if (state.mMobileType != null) { state.mMobileType.setImageDrawable(null); state.mLastMobileTypeId = -1; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java index c5616010defb..6084770f5db5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java @@ -23,13 +23,16 @@ import android.os.Bundle; import android.service.notification.StatusBarNotification; import android.view.View; +import com.android.systemui.statusbar.ExpandableNotificationRow; + /** * Wraps a notification containing a big picture template */ public class NotificationBigPictureTemplateViewWrapper extends NotificationTemplateViewWrapper { - protected NotificationBigPictureTemplateViewWrapper(Context ctx, View view) { - super(ctx, view); + protected NotificationBigPictureTemplateViewWrapper(Context ctx, View view, + ExpandableNotificationRow row) { + super(ctx, view, row); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java index 487a7a03974e..3f4912550407 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java @@ -21,6 +21,7 @@ import android.service.notification.StatusBarNotification; import android.view.View; import com.android.internal.widget.ImageFloatingTextView; +import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; /** @@ -30,8 +31,9 @@ public class NotificationBigTextTemplateViewWrapper extends NotificationTemplate private ImageFloatingTextView mBigtext; - protected NotificationBigTextTemplateViewWrapper(Context ctx, View view) { - super(ctx, view); + protected NotificationBigTextTemplateViewWrapper(Context ctx, View view, + ExpandableNotificationRow row) { + super(ctx, view, row); } private void resolveViews(StatusBarNotification notification) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java index 49e4ba8a83f5..61df44acbc50 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java @@ -30,6 +30,7 @@ import android.view.View; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; +import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.phone.NotificationPanelView; /** @@ -44,8 +45,8 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper { private boolean mShouldInvertDark; private boolean mShowingLegacyBackground; - protected NotificationCustomViewWrapper(View view) { - super(view); + protected NotificationCustomViewWrapper(View view, ExpandableNotificationRow row) { + super(view, row); mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java index b201d8fe68d9..1bfbaa228532 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java @@ -36,6 +36,7 @@ import android.widget.ImageView; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; +import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; import com.android.systemui.statusbar.phone.NotificationPanelView; @@ -61,8 +62,8 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { private ImageView mExpandButton; private NotificationHeaderView mNotificationHeader; - protected NotificationHeaderViewWrapper(Context ctx, View view) { - super(view); + protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) { + super(view, row); mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION); mTransformationHelper = new ViewTransformationHelper(); @@ -156,7 +157,9 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { } else { mInvertHelper.update(dark); } - if (mIcon != null) { + if (mIcon != null && !mRow.isChildInGroup()) { + // We don't update the color for children views / their icon is invisible anyway. + // It also may lead to bugs where the icon isn't correctly greyed out. boolean hadColorFilter = mNotificationHeader.getOriginalIconColor() != NotificationHeaderView.NO_COLOR; if (fade) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java index 30698e109178..3c95a786f8cd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java @@ -20,6 +20,7 @@ import android.content.Context; import android.service.notification.StatusBarNotification; import android.view.View; +import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; /** @@ -27,8 +28,9 @@ import com.android.systemui.statusbar.TransformableView; */ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateViewWrapper { - protected NotificationMediaTemplateViewWrapper(Context ctx, View view) { - super(ctx, view); + protected NotificationMediaTemplateViewWrapper(Context ctx, View view, + ExpandableNotificationRow row) { + super(ctx, view, row); } View mActions; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java index 78e23fce1a3e..889bd5cac7a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java @@ -25,11 +25,10 @@ import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; -import com.android.systemui.Interpolators; import com.android.systemui.statusbar.CrossFadeHelper; +import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; -import com.android.systemui.statusbar.stack.StackStateAnimator; /** * Wraps a notification view inflated from a template. @@ -43,8 +42,8 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp private TextView mTitle; private TextView mText; - protected NotificationTemplateViewWrapper(Context ctx, View view) { - super(ctx, view); + protected NotificationTemplateViewWrapper(Context ctx, View view, ExpandableNotificationRow row) { + super(ctx, view, row); mTransformationHelper.setCustomTransformation( new ViewTransformationHelper.CustomTransformation() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java index ebff69da46d1..7a0df1f54c64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java @@ -26,7 +26,7 @@ import android.view.View; import com.android.systemui.Interpolators; import com.android.systemui.statusbar.CrossFadeHelper; -import com.android.systemui.statusbar.NotificationContentView; +import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.phone.NotificationPanelView; @@ -38,28 +38,30 @@ public abstract class NotificationViewWrapper implements TransformableView { protected final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); protected final View mView; + protected final ExpandableNotificationRow mRow; protected boolean mDark; protected boolean mDarkInitialized = false; - public static NotificationViewWrapper wrap(Context ctx, View v) { + public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) { if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) { if ("bigPicture".equals(v.getTag())) { - return new NotificationBigPictureTemplateViewWrapper(ctx, v); + return new NotificationBigPictureTemplateViewWrapper(ctx, v, row); } else if ("bigText".equals(v.getTag())) { - return new NotificationBigTextTemplateViewWrapper(ctx, v); + return new NotificationBigTextTemplateViewWrapper(ctx, v, row); } else if ("media".equals(v.getTag()) || "bigMediaNarrow".equals(v.getTag())) { - return new NotificationMediaTemplateViewWrapper(ctx, v); + return new NotificationMediaTemplateViewWrapper(ctx, v, row); } - return new NotificationTemplateViewWrapper(ctx, v); + return new NotificationTemplateViewWrapper(ctx, v, row); } else if (v instanceof NotificationHeaderView) { - return new NotificationHeaderViewWrapper(ctx, v); + return new NotificationHeaderViewWrapper(ctx, v, row); } else { - return new NotificationCustomViewWrapper(v); + return new NotificationCustomViewWrapper(v, row); } } - protected NotificationViewWrapper(View view) { + protected NotificationViewWrapper(View view, ExpandableNotificationRow row) { mView = view; + mRow = row; } /** diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 6c0517387176..bc9f69e8bede 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -1048,7 +1048,13 @@ public class LockSettingsService extends ILockSettings.Stub { private void changeUserKey(int userId, byte[] token, byte[] secret) throws RemoteException { final UserInfo userInfo = UserManager.get(mContext).getUserInfo(userId); - getMountService().changeUserKey(userId, userInfo.serialNumber, token, null, secret); + final IMountService mountService = getMountService(); + final long callingId = Binder.clearCallingIdentity(); + try { + mountService.changeUserKey(userId, userInfo.serialNumber, token, null, secret); + } finally { + Binder.restoreCallingIdentity(callingId); + } } @Override diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java index 6009984842f4..f5f773214124 100644 --- a/services/core/java/com/android/server/NativeDaemonConnector.java +++ b/services/core/java/com/android/server/NativeDaemonConnector.java @@ -41,6 +41,7 @@ import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.LinkedList; @@ -344,6 +345,30 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo } /** + * Method that waits until all asychronous notifications sent by the native daemon have + * been processed. This method must not be called on the notification thread or an + * exception will be thrown. + */ + public void waitForCallbacks() { + if (Thread.currentThread() == mLooper.getThread()) { + throw new IllegalStateException("Must not call this method on callback thread"); + } + + final CountDownLatch latch = new CountDownLatch(1); + mCallbackHandler.post(new Runnable() { + @Override + public void run() { + latch.countDown(); + } + }); + try { + latch.await(); + } catch (InterruptedException e) { + Slog.wtf(TAG, "Interrupted while waiting for unsolicited response handling", e); + } + } + + /** * Issue the given command to the native daemon and return a single expected * response. * diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index fffd850ac1cb..745889847579 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -1507,6 +1507,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } + + // Ensure that before we return from this command, any asynchronous + // notifications generated before the command completed have been + // processed by all NetworkManagementEventObservers. + mConnector.waitForCallbacks(); } @Override diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 79b5978998c4..c2022d5008d8 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -273,9 +273,6 @@ public class Tethering extends BaseNetworkObserver { // ignore usb0 down after enabling RNDIS // we will handle disconnect in interfaceRemoved instead if (VDBG) Log.d(TAG, "ignore interface down for " + iface); - } else if (isWifi(iface)) { - // handle disconnect in interfaceRemoved - if (VDBG) Log.d(TAG, "ignore interface down for " + iface); } else if (sm != null) { sm.sendMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN); mIfaces.remove(iface); diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 93e4d313cce2..7ea59190981a 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -632,15 +632,6 @@ public class UserManagerService extends IUserManager.Stub { intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier()); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcastAsUser(intent, parentHandle); - - //TODO: remove once Launcher3 is updated. - Intent oldIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED); - oldIntent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode); - oldIntent.putExtra(Intent.EXTRA_USER, profileHandle); - oldIntent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier()); - oldIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - mContext.sendBroadcastAsUser(oldIntent, parentHandle); - } @Override diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 00de7e464819..ad33b4c32d7a 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -644,9 +644,12 @@ public class TaskStack implements DimLayer.DimLayerUser, Rect bounds = null; final TaskStack dockedStack = mService.mStackIdToStack.get(DOCKED_STACK_ID); if (mStackId == DOCKED_STACK_ID - || (dockedStack != null && StackId.isResizeableByDockedStack(mStackId))) { + || (dockedStack != null && StackId.isResizeableByDockedStack(mStackId) + && !dockedStack.isFullscreen())) { // The existence of a docked stack affects the size of other static stack created since - // the docked stack occupies a dedicated region on screen. + // the docked stack occupies a dedicated region on screen, but only if the dock stack is + // not fullscreen. If it's fullscreen, it means that we are in the transition of + // dismissing it, so we must not resize this stack. bounds = new Rect(); displayContent.getLogicalDisplayRect(mTmpRect); mTmpRect2.setEmpty(); diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java index 52701d532e1a..6d0808f781fe 100644 --- a/services/net/java/android/net/dhcp/DhcpClient.java +++ b/services/net/java/android/net/dhcp/DhcpClient.java @@ -264,8 +264,8 @@ public class DhcpClient extends StateMachine { mInterfaceBroadcastAddr = new PacketSocketAddress(mIface.getIndex(), DhcpPacket.ETHER_BROADCAST); return true; - } catch(SocketException e) { - Log.wtf(TAG, "Can't determine ifindex or MAC address for " + mIfaceName); + } catch(SocketException | NullPointerException e) { + Log.e(TAG, "Can't determine ifindex or MAC address for " + mIfaceName, e); return false; } } diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java index 59ebf1bc79cc..5667e340122e 100644 --- a/services/net/java/android/net/ip/IpManager.java +++ b/services/net/java/android/net/ip/IpManager.java @@ -690,7 +690,7 @@ public class IpManager extends StateMachine { final InterfaceConfiguration ifcg = new InterfaceConfiguration(); ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0")); mNwService.setInterfaceConfig(mInterfaceName, ifcg); - } catch (RemoteException e) { + } catch (IllegalStateException | RemoteException e) { Log.e(mTag, "ALERT: Failed to clear IPv4 address on interface " + mInterfaceName, e); } } |