summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--api/test-current.txt2
-rw-r--r--core/java/android/app/AlarmManager.java26
-rw-r--r--core/java/android/app/Notification.java31
-rw-r--r--core/java/android/content/Intent.java4
-rw-r--r--core/java/android/widget/DateTimeView.java12
-rw-r--r--core/java/android/widget/RemoteViews.java4
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--core/res/res/layout/notification_template_header.xml10
-rw-r--r--core/res/res/layout/notification_template_part_time.xml26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java20
-rw-r--r--services/core/java/com/android/server/LockSettingsService.java8
-rw-r--r--services/core/java/com/android/server/NativeDaemonConnector.java25
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java5
-rw-r--r--services/core/java/com/android/server/connectivity/Tethering.java3
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java9
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java7
-rw-r--r--services/net/java/android/net/dhcp/DhcpClient.java4
-rw-r--r--services/net/java/android/net/ip/IpManager.java2
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);
}
}