summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src')
-rwxr-xr-xpackages/SystemUI/src/com/android/systemui/BatteryMeterView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/Prefs.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java84
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java92
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java146
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java212
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java108
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java63
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java170
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java361
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/Util.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java162
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java168
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java181
37 files changed, 1207 insertions, 981 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 0d331d1..3fbc76b 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -225,23 +225,23 @@ public class BatteryMeterView extends View implements DemoMode,
mSubpixelSmoothingRight = context.getResources().getFraction(
R.fraction.battery_subpixel_smoothing_right, 1, 1);
- mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mFramePaint = new Paint();
mFramePaint.setColor(frameColor);
mFramePaint.setDither(true);
mFramePaint.setStrokeWidth(0);
mFramePaint.setStyle(Paint.Style.FILL_AND_STROKE);
- mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mBatteryPaint = new Paint();
mBatteryPaint.setDither(true);
mBatteryPaint.setStrokeWidth(0);
mBatteryPaint.setStyle(Paint.Style.FILL_AND_STROKE);
- mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint = new Paint();
Typeface font = Typeface.create("sans-serif-condensed", Typeface.BOLD);
mTextPaint.setTypeface(font);
mTextPaint.setTextAlign(Paint.Align.CENTER);
- mWarningTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mWarningTextPaint = new Paint();
mWarningTextPaint.setColor(mColors[1]);
font = Typeface.create("sans-serif", Typeface.BOLD);
mWarningTextPaint.setTypeface(font);
@@ -249,7 +249,7 @@ public class BatteryMeterView extends View implements DemoMode,
mChargeColor = context.getColor(R.color.batterymeter_charge_color);
- mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mBoltPaint = new Paint();
mBoltPaint.setColor(context.getColor(R.color.batterymeter_bolt_color));
mBoltPoints = loadBoltPoints(res);
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 68b1968..29d2a01 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -37,8 +37,10 @@ public final class Prefs {
Key.DND_TILE_VISIBLE,
Key.DND_TILE_COMBINED_ICON,
Key.DND_CONFIRMED_PRIORITY_INTRODUCTION,
+ Key.DND_CONFIRMED_SILENCE_INTRODUCTION,
Key.DND_FAVORITE_BUCKET_INDEX,
Key.DND_NONE_SELECTED,
+ Key.DND_FAVORITE_ZEN,
})
public @interface Key {
String SEARCH_APP_WIDGET_ID = "searchAppWidgetId";
@@ -48,8 +50,10 @@ public final class Prefs {
String DND_TILE_VISIBLE = "DndTileVisible";
String DND_TILE_COMBINED_ICON = "DndTileCombinedIcon";
String DND_CONFIRMED_PRIORITY_INTRODUCTION = "DndConfirmedPriorityIntroduction";
+ String DND_CONFIRMED_SILENCE_INTRODUCTION = "DndConfirmedSilenceIntroduction";
String DND_FAVORITE_BUCKET_INDEX = "DndCountdownMinuteIndex";
String DND_NONE_SELECTED = "DndNoneSelected";
+ String DND_FAVORITE_ZEN = "DndFavoriteZen";
}
public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 7b555fc..6479dc5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -539,10 +539,11 @@ public class KeyguardViewMediator extends SystemUI {
mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
mLockPatternUtils = new LockPatternUtils(mContext);
- mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());
+ KeyguardUpdateMonitor.setCurrentUser(ActivityManager.getCurrentUser());
// Assume keyguard is showing (unless it's disabled) until we know for sure...
- setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled());
+ setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled(
+ KeyguardUpdateMonitor.getCurrentUser()));
mTrustManager.reportKeyguardShowingChanged();
mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext,
@@ -623,8 +624,10 @@ public class KeyguardViewMediator extends SystemUI {
// Lock immediately based on setting if secure (user has a pin/pattern/password).
// This also "locks" the device when not secure to provide easy access to the
// camera while preventing unwanted input.
+ int currentUser = KeyguardUpdateMonitor.getCurrentUser();
final boolean lockImmediately =
- mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure();
+ mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
+ || !mLockPatternUtils.isSecure(currentUser);
notifyScreenOffLocked();
@@ -670,7 +673,7 @@ public class KeyguardViewMediator extends SystemUI {
// From DevicePolicyAdmin
final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
- .getMaximumTimeToLock(null, mLockPatternUtils.getCurrentUser());
+ .getMaximumTimeToLock(null, KeyguardUpdateMonitor.getCurrentUser());
long timeout;
if (policyTimeout > 0) {
@@ -719,7 +722,8 @@ public class KeyguardViewMediator extends SystemUI {
}
private void maybeSendUserPresentBroadcast() {
- if (mSystemReady && mLockPatternUtils.isLockScreenDisabled()) {
+ if (mSystemReady && mLockPatternUtils.isLockScreenDisabled(
+ KeyguardUpdateMonitor.getCurrentUser())) {
// Lock screen is disabled because the user has set the preference to "None".
// In this case, send out ACTION_USER_PRESENT here instead of in
// handleKeyguardDone()
@@ -733,7 +737,7 @@ public class KeyguardViewMediator extends SystemUI {
*/
public void onDreamingStarted() {
synchronized (this) {
- if (mScreenOn && mLockPatternUtils.isSecure()) {
+ if (mScreenOn && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
doKeyguardLaterLocked();
}
}
@@ -974,12 +978,13 @@ public class KeyguardViewMediator extends SystemUI {
return;
}
- if (mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
+ if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
+ && !lockedOrMissing) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
return;
}
- if (mLockPatternUtils.checkVoldPassword()) {
+ if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
// Without this, settings is not enabled until the lock screen first appears
setShowingLocked(false);
@@ -1072,7 +1077,7 @@ public class KeyguardViewMediator extends SystemUI {
}
public boolean isSecure() {
- return mLockPatternUtils.isSecure()
+ return mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())
|| KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure();
}
@@ -1083,7 +1088,7 @@ public class KeyguardViewMediator extends SystemUI {
* @param newUserId The id of the incoming user.
*/
public void setCurrentUser(int newUserId) {
- mLockPatternUtils.setCurrentUser(newUserId);
+ KeyguardUpdateMonitor.setCurrentUser(newUserId);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -1213,7 +1218,7 @@ public class KeyguardViewMediator extends SystemUI {
private void sendUserPresentBroadcast() {
synchronized (this) {
if (mBootCompleted) {
- final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
+ final UserHandle currentUser = new UserHandle(KeyguardUpdateMonitor.getCurrentUser());
final UserManager um = (UserManager) mContext.getSystemService(
Context.USER_SERVICE);
List <UserInfo> userHandles = um.getProfiles(currentUser.getIdentifier());
@@ -1393,14 +1398,9 @@ public class KeyguardViewMediator extends SystemUI {
updateActivityLockScreenState();
adjustStatusBarLocked();
sendUserPresentBroadcast();
- maybeStopListeningForFingerprint();
}
}
- private void maybeStopListeningForFingerprint() {
- mUpdateMonitor.stopListeningForFingerprint();
- }
-
private void adjustStatusBarLocked() {
if (mStatusBarManager == null) {
mStatusBarManager = (StatusBarManager)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 6ce63d6..5145bc7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -37,7 +37,11 @@ import com.android.systemui.volume.ZenModePanel;
/** Quick settings tile: Do not disturb **/
public class DndTile extends QSTile<QSTile.BooleanState> {
- private static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
+ private static final Intent ZEN_SETTINGS =
+ new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
+
+ private static final Intent ZEN_PRIORITY_SETTINGS =
+ new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS);
private static final String ACTION_SET_VISIBLE = "com.android.systemui.dndtile.SET_VISIBLE";
private static final String EXTRA_VISIBLE = "visible";
@@ -87,7 +91,9 @@ public class DndTile extends QSTile<QSTile.BooleanState> {
if (mState.value) {
mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
} else {
- mController.setZen(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, TAG);
+ int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
+ mController.setZen(zen, null, TAG);
+ refreshState(zen); // this one's optimistic
showDetail(true);
}
}
@@ -209,8 +215,8 @@ public class DndTile extends QSTile<QSTile.BooleanState> {
R.layout.zen_mode_panel, parent, false);
if (convertView == null) {
zmp.init(mController);
- zmp.setEmbedded(true);
zmp.addOnAttachStateChangeListener(this);
+ zmp.setCallback(mZenModePanelCallback);
}
return zmp;
}
@@ -225,4 +231,22 @@ public class DndTile extends QSTile<QSTile.BooleanState> {
mShowingDetail = false;
}
}
+
+ private final ZenModePanel.Callback mZenModePanelCallback = new ZenModePanel.Callback() {
+ @Override
+ public void onPrioritySettings() {
+ mHost.startSettingsActivity(ZEN_PRIORITY_SETTINGS);
+ }
+
+ @Override
+ public void onInteraction() {
+ // noop
+ }
+
+ @Override
+ public void onExpanded(boolean expanded) {
+ // noop
+ }
+ };
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 7271469..26c3b4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -87,6 +87,7 @@ import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.util.NotificationColorUtil;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SwipeHelper;
@@ -639,7 +640,7 @@ public abstract class BaseStatusBar extends SystemUI implements
Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 1)) {
Log.d(TAG, "user hasn't seen notification about hidden notifications");
final LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
- if (!lockPatternUtils.isSecure()) {
+ if (!lockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
Log.d(TAG, "insecure lockscreen, skipping notification");
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
@@ -708,18 +709,6 @@ public abstract class BaseStatusBar extends SystemUI implements
mNotificationListener.setNotificationsShown(keys);
}
- protected void setNotificationsShownAll() {
- ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
- final int N = activeNotifications.size();
-
- String[] keys = new String[N];
- for (int i = 0; i < N; i++) {
- NotificationData.Entry entry = activeNotifications.get(i);
- keys[i] = entry.key;
- }
- setNotificationsShown(keys);
- }
-
protected boolean isCurrentProfile(int userId) {
synchronized (mCurrentProfiles) {
return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
@@ -795,7 +784,8 @@ public abstract class BaseStatusBar extends SystemUI implements
protected void applyColorsAndBackgrounds(StatusBarNotification sbn,
NotificationData.Entry entry) {
- if (entry.expanded.getId() != com.android.internal.R.id.status_bar_latest_event_content) {
+ if (entry.getContentView().getId()
+ != com.android.internal.R.id.status_bar_latest_event_content) {
// Using custom RemoteViews
if (entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD
&& entry.targetSdk < Build.VERSION_CODES.LOLLIPOP) {
@@ -820,8 +810,9 @@ public abstract class BaseStatusBar extends SystemUI implements
public boolean isMediaNotification(NotificationData.Entry entry) {
// TODO: confirm that there's a valid media key
- return entry.expandedBig != null &&
- entry.expandedBig.findViewById(com.android.internal.R.id.media_actions) != null;
+ return entry.getExpandedContentView() != null &&
+ entry.getExpandedContentView()
+ .findViewById(com.android.internal.R.id.media_actions) != null;
}
// The gear button in the guts that links to the app's own notification settings
@@ -1145,9 +1136,9 @@ public abstract class BaseStatusBar extends SystemUI implements
}
/**
- * if the interrupting notification had a fullscreen intent, fire it now.
+ * If there is an active heads-up notification and it has a fullscreen intent, fire it now.
*/
- public abstract void escalateHeadsUp();
+ public abstract void maybeEscalateHeadsUp();
/**
* Save the current "public" (locked and secure) state of the lockscreen.
@@ -1348,8 +1339,8 @@ public abstract class BaseStatusBar extends SystemUI implements
View publicViewLocal = null;
if (publicNotification != null) {
try {
- publicViewLocal = publicNotification.contentView.apply(mContext, contentContainerPublic,
- mOnClickHandler);
+ publicViewLocal = publicNotification.contentView.apply(mContext,
+ contentContainerPublic, mOnClickHandler);
if (publicViewLocal != null) {
publicViewLocal.setIsRootNamespace(true);
@@ -1456,9 +1447,7 @@ public abstract class BaseStatusBar extends SystemUI implements
entry.row = row;
entry.row.setHeightRange(mRowMinHeight, maxHeight);
entry.row.setOnActivatedListener(this);
- entry.expanded = contentViewLocal;
- entry.expandedPublic = publicViewLocal;
- entry.setBigContentView(bigContentViewLocal);
+ entry.row.setExpandable(bigContentViewLocal != null);
applyColorsAndBackgrounds(sbn, entry);
@@ -1547,12 +1536,13 @@ public abstract class BaseStatusBar extends SystemUI implements
// See if we have somewhere to put that remote input
if (remoteInput != null) {
- if (entry.expandedBig != null) {
- inflateRemoteInput(entry.expandedBig, remoteInput, actions);
+ View bigContentView = entry.getExpandedContentView();
+ if (bigContentView != null) {
+ inflateRemoteInput(bigContentView, remoteInput, actions);
}
- View headsUpChild = entry.row.getPrivateLayout().getHeadsUpChild();
- if (headsUpChild != null) {
- inflateRemoteInput(headsUpChild, remoteInput, actions);
+ View headsUpContentView = entry.getHeadsUpContentView();
+ if (headsUpContentView != null) {
+ inflateRemoteInput(headsUpContentView, remoteInput, actions);
}
}
@@ -1701,7 +1691,6 @@ public abstract class BaseStatusBar extends SystemUI implements
boolean clearNotificationEffects =
(mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
mBarService.onPanelRevealed(clearNotificationEffects);
- setNotificationsShownAll();
} else {
mBarService.onPanelHidden();
}
@@ -1895,15 +1884,14 @@ public abstract class BaseStatusBar extends SystemUI implements
logUpdate(entry, n);
}
boolean applyInPlace = shouldApplyInPlace(entry, n);
- final boolean shouldInterrupt = shouldInterrupt(notification);
- final boolean alertAgain = alertAgain(entry, n);
+ boolean shouldInterrupt = shouldInterrupt(notification);
+ boolean alertAgain = alertAgain(entry, n);
entry.notification = notification;
mGroupManager.onEntryUpdated(entry, entry.notification);
boolean updateSuccessful = false;
if (applyInPlace) {
- // We can just reapply the notifications in place
if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
try {
if (entry.icon != null) {
@@ -1924,7 +1912,7 @@ public abstract class BaseStatusBar extends SystemUI implements
updateSuccessful = true;
}
catch (RuntimeException e) {
- // It failed to add cleanly. Log, and remove the view from the panel.
+ // It failed to apply cleanly.
Log.w(TAG, "Couldn't reapply views for package " + n.contentView.getPackage(), e);
}
}
@@ -1948,11 +1936,12 @@ public abstract class BaseStatusBar extends SystemUI implements
// swipe-dismissable)
updateNotificationVetoButton(entry.row, notification);
- // Is this for you?
- boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
- if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
+ if (DEBUG) {
+ // Is this for you?
+ boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
+ Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
+ }
- // Recalculate the position of the sliding windows and the titles.
setAreThereNotifications();
}
@@ -1963,7 +1952,7 @@ public abstract class BaseStatusBar extends SystemUI implements
StatusBarNotification oldNotification = oldEntry.notification;
Log.d(TAG, "old notification: when=" + oldNotification.getNotification().when
+ " ongoing=" + oldNotification.isOngoing()
- + " expanded=" + oldEntry.expanded
+ + " expanded=" + oldEntry.getContentView()
+ " contentView=" + oldNotification.getNotification().contentView
+ " bigContentView=" + oldNotification.getNotification().bigContentView
+ " publicView=" + oldNotification.getNotification().publicVersion
@@ -1976,7 +1965,8 @@ public abstract class BaseStatusBar extends SystemUI implements
}
/**
- * @return whether we can just reapply the RemoteViews in place when it is updated
+ * @return whether we can just reapply the RemoteViews from a notification in-place when it is
+ * updated
*/
private boolean shouldApplyInPlace(Entry entry, Notification n) {
StatusBarNotification oldNotification = entry.notification;
@@ -1994,15 +1984,15 @@ public abstract class BaseStatusBar extends SystemUI implements
final Notification publicNotification = n.publicVersion;
final RemoteViews publicContentView = publicNotification != null
? publicNotification.contentView : null;
- boolean contentsUnchanged = entry.expanded != null
+ boolean contentsUnchanged = entry.getContentView() != null
&& contentView.getPackage() != null
&& oldContentView.getPackage() != null
&& oldContentView.getPackage().equals(contentView.getPackage())
&& oldContentView.getLayoutId() == contentView.getLayoutId();
// large view may be null
boolean bigContentsUnchanged =
- (entry.getBigContentView() == null && bigContentView == null)
- || ((entry.getBigContentView() != null && bigContentView != null)
+ (entry.getExpandedContentView() == null && bigContentView == null)
+ || ((entry.getExpandedContentView() != null && bigContentView != null)
&& bigContentView.getPackage() != null
&& oldBigContentView.getPackage() != null
&& oldBigContentView.getPackage().equals(bigContentView.getPackage())
@@ -2034,12 +2024,12 @@ public abstract class BaseStatusBar extends SystemUI implements
: null;
// Reapply the RemoteViews
- contentView.reapply(mContext, entry.expanded, mOnClickHandler);
- if (bigContentView != null && entry.getBigContentView() != null) {
- bigContentView.reapply(mContext, entry.getBigContentView(),
+ contentView.reapply(mContext, entry.getContentView(), mOnClickHandler);
+ if (bigContentView != null && entry.getExpandedContentView() != null) {
+ bigContentView.reapply(mContext, entry.getExpandedContentView(),
mOnClickHandler);
}
- View headsUpChild = entry.row.getPrivateLayout().getHeadsUpChild();
+ View headsUpChild = entry.getHeadsUpContentView();
if (headsUpContentView != null && headsUpChild != null) {
headsUpContentView.reapply(mContext, headsUpChild, mOnClickHandler);
}
@@ -2062,7 +2052,7 @@ public abstract class BaseStatusBar extends SystemUI implements
}
protected void notifyHeadsUpScreenOff() {
- escalateHeadsUp();
+ maybeEscalateHeadsUp();
}
private boolean alertAgain(Entry oldEntry, Notification newNotification) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index cb8217e..9ef495d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -84,7 +84,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
private ExpansionLogger mLogger;
private String mLoggingKey;
private boolean mWasReset;
-
private NotificationGuts mGuts;
private StatusBarNotification mStatusBarNotification;
private boolean mIsHeadsUp;
@@ -102,6 +101,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
private ViewStub mGutsStub;
private boolean mHasExpandAction;
private boolean mIsSystemChildExpanded;
+ private boolean mIsPinned;
private OnClickListener mExpandClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
@@ -109,7 +109,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
!mChildrenExpanded);
}
};
- private boolean mInShade;
public NotificationContentView getPrivateLayout() {
return mPrivateLayout;
@@ -284,12 +283,18 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
return realActualHeight;
}
- public void setInShade(boolean inShade) {
- mInShade = inShade;
+ /**
+ * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
+ * the notification will be rendered on top of the screen.
+ *
+ * @param pinned whether it is pinned
+ */
+ public void setPinned(boolean pinned) {
+ mIsPinned = pinned;
}
- public boolean isInShade() {
- return mInShade;
+ public boolean isPinned() {
+ return mIsPinned;
}
public int getHeadsUpHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 1c53655..110b14c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -32,37 +32,34 @@ import android.widget.FrameLayout;
import com.android.systemui.R;
/**
- * A frame layout containing the actual payload of the notification, including the contracted and
- * expanded layout. This class is responsible for clipping the content and and switching between the
- * expanded and contracted view depending on its clipped size.
+ * A frame layout containing the actual payload of the notification, including the contracted,
+ * expanded and heads up layout. This class is responsible for clipping the content and and
+ * switching between the expanded, contracted and the heads up view depending on its clipped size.
*/
public class NotificationContentView extends FrameLayout {
private static final long ANIMATION_DURATION_LENGTH = 170;
- private static final int CONTRACTED = 1;
- private static final int EXPANDED = 2;
- private static final int HEADSUP = 3;
+ private static final int VISIBLE_TYPE_CONTRACTED = 0;
+ private static final int VISIBLE_TYPE_EXPANDED = 1;
+ private static final int VISIBLE_TYPE_HEADSUP = 2;
private final Rect mClipBounds = new Rect();
+ private final int mSmallHeight;
+ private final int mHeadsUpHeight;
+ private final Interpolator mLinearInterpolator = new LinearInterpolator();
private View mContractedChild;
private View mExpandedChild;
private View mHeadsUpChild;
private NotificationViewWrapper mContractedWrapper;
-
- private final int mSmallHeight;
- private final int mHeadsUpHeight;
private int mClipTopAmount;
-
private int mContentHeight;
-
- private final Interpolator mLinearInterpolator = new LinearInterpolator();
- private int mVisibleView = CONTRACTED;
-
+ private int mVisibleType = VISIBLE_TYPE_CONTRACTED;
private boolean mDark;
private final Paint mFadePaint = new Paint();
private boolean mAnimate;
+ private boolean mIsHeadsUp;
private ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener
= new ViewTreeObserver.OnPreDrawListener() {
@Override
@@ -72,7 +69,6 @@ public class NotificationContentView extends FrameLayout {
return true;
}
};
- private boolean mIsHeadsUp;
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -105,9 +101,9 @@ public class NotificationContentView extends FrameLayout {
// An actual height is set
size = Math.min(maxSize, layoutParams.height);
}
- int spec = size == Integer.MAX_VALUE ?
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED) :
- MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
+ int spec = size == Integer.MAX_VALUE
+ ? MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
+ : MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
mExpandedChild.measure(widthMeasureSpec, spec);
maxChildHeight = Math.max(maxChildHeight, mExpandedChild.getMeasuredHeight());
}
@@ -153,7 +149,7 @@ public class NotificationContentView extends FrameLayout {
mContractedChild = null;
mExpandedChild = null;
mHeadsUpChild = null;
- mVisibleView = CONTRACTED;
+ mVisibleType = VISIBLE_TYPE_CONTRACTED;
if (resetActualHeight) {
mContentHeight = mSmallHeight;
}
@@ -263,30 +259,32 @@ public class NotificationContentView extends FrameLayout {
if (mContractedChild == null) {
return;
}
- int visibleView = calculateVisibleView();
- if (visibleView != mVisibleView || force) {
- if (animate && mExpandedChild != null) {
- runSwitchAnimation(visibleView);
+ int visibleType = calculateVisibleType();
+ if (visibleType != mVisibleType || force) {
+ if (animate && (visibleType == VISIBLE_TYPE_EXPANDED && mExpandedChild != null)
+ || (visibleType == VISIBLE_TYPE_HEADSUP && mHeadsUpChild != null)
+ || visibleType == VISIBLE_TYPE_CONTRACTED) {
+ runSwitchAnimation(visibleType);
} else {
- updateViewVisibilities(visibleView);
+ updateViewVisibilities(visibleType);
}
- mVisibleView = visibleView;
+ mVisibleType = visibleType;
}
}
- private void updateViewVisibilities(int visibleView) {
- boolean contractedVisible = visibleView == CONTRACTED;
+ private void updateViewVisibilities(int visibleType) {
+ boolean contractedVisible = visibleType == VISIBLE_TYPE_CONTRACTED;
mContractedChild.setVisibility(contractedVisible ? View.VISIBLE : View.INVISIBLE);
mContractedChild.setAlpha(contractedVisible ? 1f : 0f);
mContractedChild.setLayerType(LAYER_TYPE_NONE, null);
if (mExpandedChild != null) {
- boolean expandedVisible = visibleView == EXPANDED;
+ boolean expandedVisible = visibleType == VISIBLE_TYPE_EXPANDED;
mExpandedChild.setVisibility(expandedVisible ? View.VISIBLE : View.INVISIBLE);
mExpandedChild.setAlpha(expandedVisible ? 1f : 0f);
mExpandedChild.setLayerType(LAYER_TYPE_NONE, null);
}
if (mHeadsUpChild != null) {
- boolean headsUpVisible = visibleView == HEADSUP;
+ boolean headsUpVisible = visibleType == VISIBLE_TYPE_HEADSUP;
mHeadsUpChild.setVisibility(headsUpVisible ? View.VISIBLE : View.INVISIBLE);
mHeadsUpChild.setAlpha(headsUpVisible ? 1f : 0f);
mHeadsUpChild.setLayerType(LAYER_TYPE_NONE, null);
@@ -294,9 +292,9 @@ public class NotificationContentView extends FrameLayout {
setLayerType(LAYER_TYPE_NONE, null);
}
- private void runSwitchAnimation(int visibleView) {
- View shownView = getViewFromFlag(visibleView);
- View hiddenView = getViewFromFlag(mVisibleView);
+ private void runSwitchAnimation(int visibleType) {
+ View shownView = getViewForVisibleType(visibleType);
+ View hiddenView = getViewForVisibleType(mVisibleType);
shownView.setVisibility(View.VISIBLE);
hiddenView.setVisibility(View.VISIBLE);
shownView.setLayerType(LAYER_TYPE_HARDWARE, mFadePaint);
@@ -314,34 +312,42 @@ public class NotificationContentView extends FrameLayout {
.withEndAction(new Runnable() {
@Override
public void run() {
- updateViewVisibilities(mVisibleView);
+ updateViewVisibilities(mVisibleType);
}
});
}
- private View getViewFromFlag(int visibleView) {
- switch (visibleView) {
- case EXPANDED:
+ /**
+ * @param visibleType one of the static enum types in this view
+ * @return the corresponding view according to the given visible type
+ */
+ private View getViewForVisibleType(int visibleType) {
+ switch (visibleType) {
+ case VISIBLE_TYPE_EXPANDED:
return mExpandedChild;
- case HEADSUP:
+ case VISIBLE_TYPE_HEADSUP:
return mHeadsUpChild;
+ default:
+ return mContractedChild;
}
- return mContractedChild;
}
- private int calculateVisibleView() {
+ /**
+ * @return one of the static enum types in this view, calculated form the current state
+ */
+ private int calculateVisibleType() {
boolean noExpandedChild = mExpandedChild == null;
if (mIsHeadsUp && mHeadsUpChild != null) {
if (mContentHeight <= mHeadsUpChild.getHeight() || noExpandedChild) {
- return HEADSUP;
+ return VISIBLE_TYPE_HEADSUP;
} else {
- return EXPANDED;
+ return VISIBLE_TYPE_EXPANDED;
}
} else {
if (mContentHeight <= mSmallHeight || noExpandedChild) {
- return CONTRACTED;
+ return VISIBLE_TYPE_CONTRACTED;
} else {
- return EXPANDED;
+ return VISIBLE_TYPE_EXPANDED;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 429889d..2a8b4ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -45,9 +45,6 @@ public class NotificationData {
public StatusBarNotification notification;
public StatusBarIconView icon;
public ExpandableNotificationRow row; // the outer expanded view
- public View expanded; // the inflated RemoteViews
- public View expandedPublic; // for insecure lockscreens
- public View expandedBig;
private boolean interruption;
public boolean autoRedacted; // whether the redacted notification was generated by us
public boolean legacy; // whether the notification has a legacy, dark background
@@ -58,14 +55,6 @@ public class NotificationData {
this.notification = n;
this.icon = ic;
}
- public void setBigContentView(View bigContentView) {
- this.expandedBig = bigContentView;
- row.setExpandable(bigContentView != null);
- }
- public View getBigContentView() {
- return expandedBig;
- }
- public View getPublicContentView() { return expandedPublic; }
public void setInterruption() {
interruption = true;
@@ -81,15 +70,28 @@ public class NotificationData {
public void reset() {
// NOTE: Icon needs to be preserved for now.
// We should fix this at some point.
- expanded = null;
- expandedPublic = null;
- expandedBig = null;
autoRedacted = false;
legacy = false;
if (row != null) {
row.reset();
}
}
+
+ public View getContentView() {
+ return row.getPrivateLayout().getContractedChild();
+ }
+
+ public View getExpandedContentView() {
+ return row.getPrivateLayout().getExpandedChild();
+ }
+
+ public View getHeadsUpContentView() {
+ return row.getPrivateLayout().getHeadsUpChild();
+ }
+
+ public View getPublicContentView() {
+ return row.getPublicLayout().getContractedChild();
+ }
}
private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
@@ -258,7 +260,7 @@ public class NotificationData {
*/
public boolean hasActiveClearableNotifications() {
for (Entry e : mSortedAndFiltered) {
- if (e.expanded != null) { // the view successfully inflated
+ if (e.getContentView() != null) { // the view successfully inflated
if (e.notification.isClearable()) {
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 3997807..fe7bc97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -27,7 +27,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
/**
- * A Helper class to handle touches on the heads-up views
+ * A helper class to handle touches on the heads-up views.
*/
public class HeadsUpTouchHelper implements Gefingerpoken {
@@ -37,19 +37,30 @@ public class HeadsUpTouchHelper implements Gefingerpoken {
private float mTouchSlop;
private float mInitialTouchX;
private float mInitialTouchY;
- private boolean mMotionOnHeadsUpView;
+ private boolean mTouchingHeadsUpView;
private boolean mTrackingHeadsUp;
private boolean mCollapseSnoozes;
private NotificationPanelView mPanel;
private ExpandableNotificationRow mPickedChild;
+ public HeadsUpTouchHelper(HeadsUpManager headsUpManager,
+ NotificationStackScrollLayout stackScroller,
+ NotificationPanelView notificationPanelView) {
+ mHeadsUpManager = headsUpManager;
+ mStackScroller = stackScroller;
+ mPanel = notificationPanelView;
+ Context context = stackScroller.getContext();
+ final ViewConfiguration configuration = ViewConfiguration.get(context);
+ mTouchSlop = configuration.getScaledTouchSlop();
+ }
+
public boolean isTrackingHeadsUp() {
return mTrackingHeadsUp;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- if (!mMotionOnHeadsUpView && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
+ if (!mTouchingHeadsUpView && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
return false;
}
int pointerIndex = event.findPointerIndex(mTrackingPointer);
@@ -65,10 +76,10 @@ public class HeadsUpTouchHelper implements Gefingerpoken {
mInitialTouchX = x;
setTrackingHeadsUp(false);
ExpandableView child = mStackScroller.getChildAtPosition(x, y);
- mMotionOnHeadsUpView = false;
+ mTouchingHeadsUpView = false;
if (child instanceof ExpandableNotificationRow) {
mPickedChild = (ExpandableNotificationRow) child;
- mMotionOnHeadsUpView = mPickedChild.isHeadsUp() && !mPickedChild.isInShade();
+ mTouchingHeadsUpView = mPickedChild.isHeadsUp() && mPickedChild.isPinned();
}
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -97,7 +108,8 @@ public class HeadsUpTouchHelper implements Gefingerpoken {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- if (mPickedChild != null && mMotionOnHeadsUpView) {
+ if (mPickedChild != null && mTouchingHeadsUpView) {
+ // We may swallow this click if the heads up just came in.
if (mHeadsUpManager.shouldSwallowClick(
mPickedChild.getStatusBarNotification().getKey())) {
endMotion();
@@ -141,20 +153,6 @@ public class HeadsUpTouchHelper implements Gefingerpoken {
private void endMotion() {
mTrackingPointer = -1;
mPickedChild = null;
- mMotionOnHeadsUpView = false;
- }
-
- public ExpandableView getPickedChild() {
- return mPickedChild;
- }
-
- public void bind(HeadsUpManager headsUpManager, NotificationStackScrollLayout stackScroller,
- NotificationPanelView notificationPanelView) {
- mHeadsUpManager = headsUpManager;
- mStackScroller = stackScroller;
- mPanel = notificationPanelView;
- Context context = stackScroller.getContext();
- final ViewConfiguration configuration = ViewConfiguration.get(context);
- mTouchSlop = configuration.getScaledTouchSlop();
+ mTouchingHeadsUpView = false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index e5ef6ff..fabc1a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -86,7 +86,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private KeyguardAffordanceView mCameraImageView;
private KeyguardAffordanceView mPhoneImageView;
- private KeyguardAffordanceView mLockIcon;
+ private LockIcon mLockIcon;
private TextView mIndicationText;
private ViewGroup mPreviewContainer;
@@ -102,11 +102,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private AccessibilityController mAccessibilityController;
private PhoneStatusBar mPhoneStatusBar;
- private final TrustDrawable mTrustDrawable;
private final Interpolator mLinearOutSlowInInterpolator;
- private int mLastUnlockIconRes = 0;
private boolean mPrewarmSent;
- private boolean mTransientFpError;
public KeyguardBottomAreaView(Context context) {
this(context, null);
@@ -123,7 +120,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mTrustDrawable = new TrustDrawable(mContext);
mLinearOutSlowInInterpolator =
AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
}
@@ -169,20 +165,19 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container);
mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
mPhoneImageView = (KeyguardAffordanceView) findViewById(R.id.phone_button);
- mLockIcon = (KeyguardAffordanceView) findViewById(R.id.lock_icon);
+ mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
watchForCameraPolicyChanges();
updateCameraVisibility();
updatePhoneVisibility();
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
mUnlockMethodCache.addListener(this);
- updateLockIcon();
+ mLockIcon.update();
setClipChildren(false);
setClipToPadding(false);
mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
inflatePreviews();
mLockIcon.setOnClickListener(this);
- mLockIcon.setBackground(mTrustDrawable);
mLockIcon.setOnLongClickListener(this);
mCameraImageView.setOnClickListener(this);
mPhoneImageView.setOnClickListener(this);
@@ -222,6 +217,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
public void setAccessibilityController(AccessibilityController accessibilityController) {
mAccessibilityController = accessibilityController;
+ mLockIcon.setAccessibilityController(accessibilityController);
accessibilityController.addStateChangedCallback(this);
}
@@ -233,9 +229,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private Intent getCameraIntent() {
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
boolean currentUserHasTrust = updateMonitor.getUserHasTrust(
- mLockPatternUtils.getCurrentUser());
- return mLockPatternUtils.isSecure() && !currentUserHasTrust
- ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
+ KeyguardUpdateMonitor.getCurrentUser());
+ boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
+ return (secure && !currentUserHasTrust) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
}
private void updateCameraVisibility() {
@@ -245,7 +241,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
ResolveInfo resolved = mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
PackageManager.MATCH_DEFAULT_ONLY,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
boolean visible = !isCameraDisabledByDpm() && resolved != null
&& getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance);
mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
@@ -294,21 +290,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mPhoneImageView.setClickable(touchExplorationEnabled);
mCameraImageView.setFocusable(accessibilityEnabled);
mPhoneImageView.setFocusable(accessibilityEnabled);
- updateLockIconClickability();
- }
-
- private void updateLockIconClickability() {
- if (mAccessibilityController == null) {
- return;
- }
- boolean clickToUnlock = mAccessibilityController.isTouchExplorationEnabled();
- boolean clickToForceLock = mUnlockMethodCache.isTrustManaged()
- && !mAccessibilityController.isAccessibilityEnabled();
- boolean longClickToForceLock = mUnlockMethodCache.isTrustManaged()
- && !clickToForceLock;
- mLockIcon.setClickable(clickToForceLock || clickToUnlock);
- mLockIcon.setLongClickable(longClickToForceLock);
- mLockIcon.setFocusable(mAccessibilityController.isAccessibilityEnabled());
+ mLockIcon.update();
}
@Override
@@ -339,13 +321,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
0 /* velocityDp - N/A */);
mIndicationController.showTransientIndication(
R.string.keyguard_indication_trust_disabled);
- mLockPatternUtils.requireCredentialEntry(mLockPatternUtils.getCurrentUser());
+ mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser());
}
public void prewarmCamera() {
Intent intent = getCameraIntent();
String targetPackage = PreviewInflater.getTargetPackage(mContext, intent,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
if (targetPackage != null) {
Intent prewarm = new Intent(MediaStore.ACTION_STILL_IMAGE_CAMERA_PREWARM);
prewarm.setPackage(targetPackage);
@@ -361,7 +343,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mPrewarmSent = false;
Intent intent = getCameraIntent();
String targetPackage = PreviewInflater.getTargetPackage(mContext, intent,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
if (targetPackage != null) {
Intent prewarm = new Intent(MediaStore.ACTION_STILL_IMAGE_CAMERA_COOLDOWN);
prewarm.setPackage(targetPackage);
@@ -375,7 +357,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mPrewarmSent = false;
final Intent intent = getCameraIntent();
boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
- mContext, intent, mLockPatternUtils.getCurrentUser());
+ mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
AsyncTask.execute(new Runnable() {
@Override
@@ -409,69 +391,12 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
- if (isShown()) {
- mTrustDrawable.start();
- } else {
- mTrustDrawable.stop();
- }
if (changedView == this && visibility == VISIBLE) {
- updateLockIcon();
+ mLockIcon.update();
updateCameraVisibility();
}
}
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mTrustDrawable.stop();
- }
-
- private void updateLockIcon() {
- boolean visible = isShown() && KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
- if (visible) {
- mTrustDrawable.start();
- } else {
- mTrustDrawable.stop();
- }
- if (!visible) {
- return;
- }
- // TODO: Real icon for facelock.
- boolean isFingerprintIcon =
- KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning();
- boolean anyFingerprintIcon = isFingerprintIcon || mTransientFpError;
- int iconRes = mTransientFpError ? R.drawable.ic_fingerprint_error
- : isFingerprintIcon ? R.drawable.ic_fingerprint
- : mUnlockMethodCache.isFaceUnlockRunning()
- ? com.android.internal.R.drawable.ic_account_circle
- : mUnlockMethodCache.isCurrentlyInsecure() ? R.drawable.ic_lock_open_24dp
- : R.drawable.ic_lock_24dp;
-
- if (mLastUnlockIconRes != iconRes) {
- Drawable icon = mContext.getDrawable(iconRes);
- int iconHeight = getResources().getDimensionPixelSize(
- R.dimen.keyguard_affordance_icon_height);
- int iconWidth = getResources().getDimensionPixelSize(
- R.dimen.keyguard_affordance_icon_width);
- if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
- || icon.getIntrinsicWidth() != iconWidth)) {
- icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
- }
- mLockIcon.setImageDrawable(icon);
- mLockIcon.setPaddingRelative(0, 0, 0, anyFingerprintIcon
- ? getResources().getDimensionPixelSize(
- R.dimen.fingerprint_icon_additional_padding)
- : 0);
- mLockIcon.setRestingAlpha(
- anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
- }
-
- // Hide trust circle when fingerprint is running.
- boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !anyFingerprintIcon;
- mTrustDrawable.setTrustManaged(trustManaged);
- updateLockIconClickability();
- }
-
public KeyguardAffordanceView getPhoneView() {
return mPhoneImageView;
}
@@ -503,7 +428,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
@Override
public void onUnlockMethodStateChanged() {
- updateLockIcon();
+ mLockIcon.update();
updateCameraVisibility();
}
@@ -563,9 +488,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private final Runnable mTransientFpErrorClearRunnable = new Runnable() {
@Override
public void run() {
- mTransientFpError = false;
+ mLockIcon.setTransientFpError(false);
mIndicationController.hideTransientIndication();
- updateLockIcon();
}
};
@@ -578,17 +502,17 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
@Override
public void onScreenTurnedOn() {
- updateLockIcon();
+ mLockIcon.update();
}
@Override
public void onScreenTurnedOff(int why) {
- updateLockIcon();
+ mLockIcon.update();
}
@Override
public void onKeyguardVisibilityChanged(boolean showing) {
- updateLockIcon();
+ mLockIcon.update();
}
@Override
@@ -597,24 +521,21 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
@Override
public void onFingerprintRunningStateChanged(boolean running) {
- updateLockIcon();
+ mLockIcon.update();
}
@Override
public void onFingerprintHelp(int msgId, String helpString) {
- mTransientFpError = true;
+ mLockIcon.setTransientFpError(true);
mIndicationController.showTransientIndication(helpString,
getResources().getColor(R.color.system_warning_color, null));
removeCallbacks(mTransientFpErrorClearRunnable);
postDelayed(mTransientFpErrorClearRunnable, TRANSIENT_FP_ERROR_TIMEOUT);
- updateLockIcon();
}
@Override
public void onFingerprintError(int msgId, String errString) {
// TODO: Go to bouncer if this is "too many attempts" (lockout) error.
- Log.i(TAG, "FP Error: " + errString);
- updateLockIcon();
}
};
@@ -622,29 +543,4 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
KeyguardIndicationController keyguardIndicationController) {
mIndicationController = keyguardIndicationController;
}
-
- /**
- * A wrapper around another Drawable that overrides the intrinsic size.
- */
- private static class IntrinsicSizeDrawable extends InsetDrawable {
-
- private final int mIntrinsicWidth;
- private final int mIntrinsicHeight;
-
- public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
- super(drawable, 0);
- mIntrinsicWidth = intrinsicWidth;
- mIntrinsicHeight = intrinsicHeight;
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mIntrinsicWidth;
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mIntrinsicHeight;
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
new file mode 100644
index 0000000..66f3232
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.policy.AccessibilityController;
+
+/**
+ * Manages the different states and animations of the unlock icon.
+ */
+public class LockIcon extends KeyguardAffordanceView {
+
+
+ private static final int STATE_LOCKED = 0;
+ private static final int STATE_LOCK_OPEN = 1;
+ private static final int STATE_FACE_UNLOCK = 2;
+ private static final int STATE_FINGERPRINT = 3;
+ private static final int STATE_FINGERPRINT_ERROR = 4;
+
+ private int mLastState = 0;
+ private boolean mTransientFpError;
+ private final TrustDrawable mTrustDrawable;
+ private final UnlockMethodCache mUnlockMethodCache;
+ private AccessibilityController mAccessibilityController;
+
+ public LockIcon(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mTrustDrawable = new TrustDrawable(context);
+ setBackground(mTrustDrawable);
+ mUnlockMethodCache = UnlockMethodCache.getInstance(context);
+ }
+
+ @Override
+ protected void onVisibilityChanged(View changedView, int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+ if (isShown()) {
+ mTrustDrawable.start();
+ } else {
+ mTrustDrawable.stop();
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mTrustDrawable.stop();
+ }
+
+ public void setTransientFpError(boolean transientFpError) {
+ mTransientFpError = transientFpError;
+ update();
+ }
+
+ public void update() {
+ boolean visible = isShown() && KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
+ if (visible) {
+ mTrustDrawable.start();
+ } else {
+ mTrustDrawable.stop();
+ }
+ if (!visible) {
+ return;
+ }
+ // TODO: Real icon for facelock.
+ int state = getState();
+ boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
+ if (state != mLastState) {
+ int iconRes = getAnimationResForTransition(mLastState, state);
+ if (iconRes == -1) {
+ iconRes = getIconForState(state);
+ }
+ Drawable icon = mContext.getDrawable(iconRes);
+ AnimatedVectorDrawable animation = null;
+ if (icon instanceof AnimatedVectorDrawable) {
+ animation = (AnimatedVectorDrawable) icon;
+ }
+ int iconHeight = getResources().getDimensionPixelSize(
+ R.dimen.keyguard_affordance_icon_height);
+ int iconWidth = getResources().getDimensionPixelSize(
+ R.dimen.keyguard_affordance_icon_width);
+ if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
+ || icon.getIntrinsicWidth() != iconWidth)) {
+ icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
+ }
+ setPaddingRelative(0, 0, 0, anyFingerprintIcon
+ ? getResources().getDimensionPixelSize(
+ R.dimen.fingerprint_icon_additional_padding)
+ : 0);
+ setRestingAlpha(
+ anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
+ setImageDrawable(icon);
+ if (animation != null) {
+ animation.start();
+ }
+ }
+
+ // Hide trust circle when fingerprint is running.
+ boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !anyFingerprintIcon;
+ mTrustDrawable.setTrustManaged(trustManaged);
+ mLastState = state;
+ updateClickability();
+ }
+
+ private void updateClickability() {
+ if (mAccessibilityController == null) {
+ return;
+ }
+ boolean clickToUnlock = mAccessibilityController.isTouchExplorationEnabled();
+ boolean clickToForceLock = mUnlockMethodCache.isTrustManaged()
+ && !mAccessibilityController.isAccessibilityEnabled();
+ boolean longClickToForceLock = mUnlockMethodCache.isTrustManaged()
+ && !clickToForceLock;
+ setClickable(clickToForceLock || clickToUnlock);
+ setLongClickable(longClickToForceLock);
+ setFocusable(mAccessibilityController.isAccessibilityEnabled());
+ }
+
+ public void setAccessibilityController(AccessibilityController accessibilityController) {
+ mAccessibilityController = accessibilityController;
+ }
+
+ private int getIconForState(int state) {
+ switch (state) {
+ case STATE_LOCKED:
+ return R.drawable.ic_lock_24dp;
+ case STATE_LOCK_OPEN:
+ return R.drawable.ic_lock_open_24dp;
+ case STATE_FACE_UNLOCK:
+ return com.android.internal.R.drawable.ic_account_circle;
+ case STATE_FINGERPRINT:
+ return R.drawable.ic_fingerprint;
+ case STATE_FINGERPRINT_ERROR:
+ return R.drawable.ic_fingerprint_error;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private int getAnimationResForTransition(int oldState, int newState) {
+ if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
+ return R.drawable.lockscreen_fingerprint_error_state_animation;
+ } else {
+ return -1;
+ }
+ }
+
+ private int getState() {
+ boolean fingerprintRunning =
+ KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning();
+ if (mTransientFpError) {
+ return STATE_FINGERPRINT_ERROR;
+ } else if (fingerprintRunning) {
+ return STATE_FINGERPRINT;
+ } else if (mUnlockMethodCache.isFaceUnlockRunning()) {
+ return STATE_FACE_UNLOCK;
+ } else if (mUnlockMethodCache.isCurrentlyInsecure()) {
+ return STATE_LOCK_OPEN;
+ } else {
+ return STATE_LOCKED;
+ }
+ }
+
+ /**
+ * A wrapper around another Drawable that overrides the intrinsic size.
+ */
+ private static class IntrinsicSizeDrawable extends InsetDrawable {
+
+ private final int mIntrinsicWidth;
+ private final int mIntrinsicHeight;
+
+ public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
+ super(drawable, 0);
+ mIntrinsicWidth = intrinsicWidth;
+ mIntrinsicHeight = intrinsicHeight;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mIntrinsicWidth;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mIntrinsicHeight;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index b87c25b..a8ecc42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -182,11 +182,11 @@ public class NotificationPanelView extends PanelView implements
private float mKeyguardStatusBarAnimateAlpha = 1f;
private int mOldLayoutDirection;
- private HeadsUpTouchHelper mHeadsUpTouchHelper = new HeadsUpTouchHelper();
- private boolean mPinnedHeadsUpExist;
- private boolean mExpansionIsFromHeadsUp;
- private int mBottomBarHeight;
+ private HeadsUpTouchHelper mHeadsUpTouchHelper;
+ private boolean mIsExpansionFromHeadsUp;
+ private int mNavigationBarBottomHeight;
private boolean mExpandingFromHeadsUp;
+ private boolean mCollapsedOnDown;
private int mPositionMinSideMargin;
private int mLastOrientation = -1;
@@ -327,7 +327,7 @@ public class NotificationPanelView extends PanelView implements
} else if (!mQsExpanded) {
setQsExpansion(mQsMinExpansionHeight + mLastOverscroll);
}
- mNotificationStackScroller.setStackHeight(getExpandedHeight());
+ updateStackHeight(getExpandedHeight());
updateHeader();
mNotificationStackScroller.updateIsSmallScreen(
mHeader.getCollapsedHeight() + mQsPeekHeight);
@@ -534,17 +534,16 @@ public class NotificationPanelView extends PanelView implements
}
@Override
- public boolean
- onInterceptTouchEvent(MotionEvent event) {
+ public boolean onInterceptTouchEvent(MotionEvent event) {
if (mBlockTouches) {
return false;
}
initDownStates(event);
if (mHeadsUpTouchHelper.onInterceptTouchEvent(event)) {
- mExpansionIsFromHeadsUp = true;
+ mIsExpansionFromHeadsUp = true;
return true;
}
- if (!isShadeCollapsed() && onQsIntercept(event)) {
+ if (!isFullyCollapsed() && onQsIntercept(event)) {
return true;
}
return super.onInterceptTouchEvent(event);
@@ -641,6 +640,7 @@ public class NotificationPanelView extends PanelView implements
mOnlyAffordanceInThisMotion = false;
mQsTouchAboveFalsingThreshold = mQsFullyExpanded;
mDozingOnDown = isDozing();
+ mCollapsedOnDown = isFullyCollapsed();
}
}
@@ -695,7 +695,7 @@ public class NotificationPanelView extends PanelView implements
return true;
}
mHeadsUpTouchHelper.onTouchEvent(event);
- if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQSTouch(event)) {
+ if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
return true;
}
if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
@@ -705,7 +705,7 @@ public class NotificationPanelView extends PanelView implements
return true;
}
- private boolean handleQSTouch(MotionEvent event) {
+ private boolean handleQsTouch(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
&& mStatusBar.getBarState() != StatusBarState.KEYGUARD && !mQsExpanded
&& mQsExpansionEnabled) {
@@ -718,7 +718,7 @@ public class NotificationPanelView extends PanelView implements
mInitialTouchY = event.getX();
mInitialTouchX = event.getY();
}
- if (!isShadeCollapsed()) {
+ if (!isFullyCollapsed()) {
handleQsDown(event);
}
if (!mQsExpandImmediate && mQsTracking) {
@@ -731,7 +731,7 @@ public class NotificationPanelView extends PanelView implements
|| event.getActionMasked() == MotionEvent.ACTION_UP) {
mConflictingQsExpansionGesture = false;
}
- if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isShadeCollapsed()
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()
&& mQsExpansionEnabled) {
mTwoFingerQsExpandPossible = true;
}
@@ -1191,8 +1191,8 @@ public class NotificationPanelView extends PanelView implements
updateEmptyShadeView();
mQsNavbarScrim.setVisibility(mStatusBarState == StatusBarState.SHADE && mQsExpanded
&& !mStackScrollerOverscrolling && mQsScrimEnabled
- ? View.VISIBLE
- : View.INVISIBLE);
+ ? View.VISIBLE
+ : View.INVISIBLE);
if (mKeyguardUserSwitcher != null && mQsExpanded && !mStackScrollerOverscrolling) {
mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
}
@@ -1386,7 +1386,7 @@ public class NotificationPanelView extends PanelView implements
* @return Whether we should intercept a gesture to open Quick Settings.
*/
private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
- if (!mQsExpansionEnabled) {
+ if (!mQsExpansionEnabled || mCollapsedOnDown) {
return false;
}
View header = mKeyguardShowing ? mKeyguardStatusBar : mHeader;
@@ -1457,12 +1457,12 @@ public class NotificationPanelView extends PanelView implements
setQsExpansion(mQsMinExpansionHeight
+ t * (getTempQsMaxExpansion() - mQsMinExpansionHeight));
}
- mNotificationStackScroller.setStackHeight(expandedHeight);
+ updateStackHeight(expandedHeight);
updateHeader();
updateUnlockIcon();
updateNotificationTranslucency();
- mHeadsUpManager.setIsExpanded(!isShadeCollapsed());
- mNotificationStackScroller.setShadeExpanded(!isShadeCollapsed());
+ mHeadsUpManager.setIsExpanded(!isFullyCollapsed());
+ mNotificationStackScroller.setShadeExpanded(!isFullyCollapsed());
if (DEBUG) {
invalidate();
}
@@ -1535,21 +1535,19 @@ public class NotificationPanelView extends PanelView implements
float alpha;
if (mExpandingFromHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()) {
alpha = 1f;
- if (mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) {
- mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null);
- }
} else {
alpha = (getNotificationsTopY() + mNotificationStackScroller.getItemHeight())
/ (mQsMinExpansionHeight + mNotificationStackScroller.getBottomStackPeekSize()
- mNotificationStackScroller.getCollapseSecondCardPadding());
alpha = Math.max(0, Math.min(alpha, 1));
alpha = (float) Math.pow(alpha, 0.75);
- if (alpha != 1f && mNotificationStackScroller.getLayerType() != LAYER_TYPE_HARDWARE) {
- mNotificationStackScroller.setLayerType(LAYER_TYPE_HARDWARE, null);
- } else if (alpha == 1f
- && mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) {
- mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null);
- }
+ }
+
+ if (alpha != 1f && mNotificationStackScroller.getLayerType() != LAYER_TYPE_HARDWARE) {
+ mNotificationStackScroller.setLayerType(LAYER_TYPE_HARDWARE, null);
+ } else if (alpha == 1f
+ && mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) {
+ mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null);
}
mNotificationStackScroller.setAlpha(alpha);
}
@@ -1615,7 +1613,7 @@ public class NotificationPanelView extends PanelView implements
}
float stackTranslation = mNotificationStackScroller.getStackTranslation();
float translation = stackTranslation / HEADER_RUBBERBAND_FACTOR;
- if (mHeadsUpManager.hasPinnedHeadsUp() || mExpansionIsFromHeadsUp) {
+ if (mHeadsUpManager.hasPinnedHeadsUp() || mIsExpansionFromHeadsUp) {
translation = mNotificationStackScroller.getTopPadding() + stackTranslation
- mNotificationTopPadding - mQsMinExpansionHeight;
}
@@ -1683,16 +1681,16 @@ public class NotificationPanelView extends PanelView implements
mHeadsUpManager.onExpandingFinished();
mIsExpanding = false;
mScrollYOverride = -1;
- if (isShadeCollapsed()) {
+ if (isFullyCollapsed()) {
setListening(false);
} else {
setListening(true);
}
mQsExpandImmediate = false;
mTwoFingerQsExpandPossible = false;
- mExpansionIsFromHeadsUp = false;
- mNotificationStackScroller.setTrackingHeadsUp(mHeadsUpTouchHelper.isTrackingHeadsUp());
- mExpandingFromHeadsUp = mHeadsUpTouchHelper.isTrackingHeadsUp();
+ mIsExpansionFromHeadsUp = false;
+ mNotificationStackScroller.setTrackingHeadsUp(false);
+ mExpandingFromHeadsUp = false;
}
private void setListening(boolean listening) {
@@ -1793,13 +1791,13 @@ public class NotificationPanelView extends PanelView implements
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- mBottomBarHeight = insets.getSystemWindowInsetBottom();
+ mNavigationBarBottomHeight = insets.getSystemWindowInsetBottom();
updateMaxHeadsUpTranslation();
return insets;
}
private void updateMaxHeadsUpTranslation() {
- mNotificationStackScroller.setHeadsUpBoundaries(getHeight(), mBottomBarHeight);
+ mNotificationStackScroller.setHeadsUpBoundaries(getHeight(), mNavigationBarBottomHeight);
}
@Override
@@ -2160,48 +2158,43 @@ public class NotificationPanelView extends PanelView implements
}
@Override
- public void OnPinnedHeadsUpExistChanged(final boolean exist, boolean changeImmediatly) {
- if (exist != mPinnedHeadsUpExist) {
- mPinnedHeadsUpExist = exist;
- if (exist) {
- mHeadsUpExistenceChangedRunnable.run();
- updateNotificationTranslucency();
- } else {
- mNotificationStackScroller.performOnAnimationFinished(
- mHeadsUpExistenceChangedRunnable);
- }
+ public void onHeadsUpPinnedModeChanged(final boolean inPinnedMode) {
+ if (inPinnedMode) {
+ mHeadsUpExistenceChangedRunnable.run();
+ updateNotificationTranslucency();
+ } else {
+ mNotificationStackScroller.runAfterAnimationFinished(
+ mHeadsUpExistenceChangedRunnable);
}
}
@Override
- public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
- if (isHeadsUp) {
- mNotificationStackScroller.generateHeadsUpAnimation(headsUp, true);
- }
+ public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
+ mNotificationStackScroller.generateHeadsUpAnimation(headsUp, true);
}
@Override
- public void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
- mNotificationStackScroller.generateHeadsUpAnimation(entry.row, isHeadsUp);
+ public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
}
@Override
- protected boolean isShadeCollapsed() {
- return mExpandedHeight == 0;
+ public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
+ mNotificationStackScroller.generateHeadsUpAnimation(entry.row, isHeadsUp);
}
@Override
public void setHeadsUpManager(HeadsUpManager headsUpManager) {
super.setHeadsUpManager(headsUpManager);
- mHeadsUpTouchHelper.bind(headsUpManager, mNotificationStackScroller, this);
+ mHeadsUpTouchHelper = new HeadsUpTouchHelper(headsUpManager, mNotificationStackScroller,
+ this);
}
public void setTrackingHeadsUp(boolean tracking) {
if (tracking) {
- // otherwise we update the state when the expansion is finished
mNotificationStackScroller.setTrackingHeadsUp(true);
mExpandingFromHeadsUp = true;
}
+ // otherwise we update the state when the expansion is finished
}
@Override
@@ -2241,4 +2234,9 @@ public class NotificationPanelView extends PanelView implements
mScrollView.setTranslationX(translation);
mHeader.setTranslationX(translation);
}
+
+ private void updateStackHeight(float stackHeight) {
+ mNotificationStackScroller.setStackHeight(stackHeight);
+ updateKeyguardBottomAreaAlpha();
+ }
}
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 4452dd7..85f312c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -46,13 +46,13 @@ import java.io.PrintWriter;
public abstract class PanelView extends FrameLayout {
public static final boolean DEBUG = PanelBar.DEBUG;
public static final String TAG = PanelView.class.getSimpleName();
- protected HeadsUpManager mHeadsUpManager;
-
private final void logf(String fmt, Object... args) {
Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
}
protected PhoneStatusBar mStatusBar;
+ protected HeadsUpManager mHeadsUpManager;
+
private float mPeekHeight;
private float mHintDistance;
private int mEdgeTapAreaWidth;
@@ -242,15 +242,15 @@ public abstract class PanelView extends FrameLayout {
final float y = event.getY(pointerIndex);
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mGestureWaitForTouchSlop = isShadeCollapsed() || hasConflictingGestures();
- mIgnoreXTouchSlop = isShadeCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
+ mGestureWaitForTouchSlop = isFullyCollapsed() || hasConflictingGestures();
+ mIgnoreXTouchSlop = isFullyCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
}
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
startExpandMotion(x, y, false /* startTracking */, mExpandedHeight);
mJustPeeked = false;
- mPanelClosedOnDown = isShadeCollapsed();
+ mPanelClosedOnDown = isFullyCollapsed();
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mMotionAborted = false;
@@ -268,7 +268,7 @@ public abstract class PanelView extends FrameLayout {
|| mPeekPending || mPeekAnimator != null;
onTrackingStarted();
}
- if (isShadeCollapsed()) {
+ if (isFullyCollapsed()) {
schedulePeek();
}
break;
@@ -472,7 +472,7 @@ public abstract class PanelView extends FrameLayout {
mTouchSlopExceeded = false;
mJustPeeked = false;
mMotionAborted = false;
- mPanelClosedOnDown = isShadeCollapsed();
+ mPanelClosedOnDown = isFullyCollapsed();
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mTouchAboveFalsingThreshold = false;
@@ -707,7 +707,7 @@ public abstract class PanelView extends FrameLayout {
// If the user isn't actively poking us, let's update the height
if ((!mTracking || isTrackingBlocked())
&& mHeightAnimator == null
- && !isShadeCollapsed()
+ && !isFullyCollapsed()
&& currentMaxPanelHeight != mExpandedHeight
&& !mPeekPending
&& mPeekAnimator == null
@@ -1057,8 +1057,6 @@ public abstract class PanelView extends FrameLayout {
*/
protected abstract int getClearAllHeight();
- protected abstract boolean isShadeCollapsed();
-
public void setHeadsUpManager(HeadsUpManager headsUpManager) {
mHeadsUpManager = headsUpManager;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 6b17589..9a6a80e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1152,11 +1152,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
@Override
public void removeNotification(String key, RankingMap ranking) {
- boolean defferRemoval = false;
+ boolean deferRemoval = false;
if (mHeadsUpManager.isHeadsUp(key)) {
- defferRemoval = !mHeadsUpManager.removeNotification(key);
+ deferRemoval = !mHeadsUpManager.removeNotification(key);
}
- if (defferRemoval) {
+ if (deferRemoval) {
mLatestRankingMap = ranking;
mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
return;
@@ -1293,13 +1293,20 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
updateClearAll();
updateEmptyShadeView();
- // Disable QS if device not provisioned.
- // If the user switcher is simple then disable QS during setup because
- // the user intends to use the lock screen user switcher, QS in not needed.
+ updateQsExpansionEnabled();
+ mShadeUpdates.check();
+ }
+
+ /**
+ * Disable QS if device not provisioned.
+ * If the user switcher is simple then disable QS during setup because
+ * the user intends to use the lock screen user switcher, QS in not needed.
+ */
+ private void updateQsExpansionEnabled() {
mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
&& (mUserSetup || mUserSwitcherController == null
- || !mUserSwitcherController.isSimpleUserSwitcher()));
- mShadeUpdates.check();
+ || !mUserSwitcherController.isSimpleUserSwitcher())
+ && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0));
}
private void updateNotificationShadeForChildren() {
@@ -1732,6 +1739,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
flagdbg.append(((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
flagdbg.append(((state1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
flagdbg.append(((diff1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
+ flagdbg.append(((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "QUICK_SETTINGS"
+ : "quick_settings");
+ flagdbg.append(((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "* " : " ");
flagdbg.append(">");
Log.d(TAG, flagdbg.toString());
@@ -1780,6 +1790,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
(state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
mHeadsUpObserver.onChange(true);
}
+
+ if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
+ updateQsExpansionEnabled();
+ }
}
@Override
@@ -1838,8 +1852,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
- public void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly) {
- if (exist) {
+ public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
+ if (inPinnedMode) {
mStatusBarWindowManager.setHeadsUpShowing(true);
} else {
Runnable endRunnable = new Runnable() {
@@ -1850,20 +1864,25 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
};
- if (changeImmediatly) {
+ if (!mNotificationPanel.isFullyCollapsed()) {
endRunnable.run();
} else {
- mStackScroller.performOnAnimationFinished(endRunnable);
+ mStackScroller.runAfterAnimationFinished(endRunnable);
}
}
}
@Override
- public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
+ public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
+ dismissVolumeDialog();
}
@Override
- public void OnHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
+ public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
+ }
+
+ @Override
+ public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
removeNotification(entry.key, mLatestRankingMap);
mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
@@ -1880,10 +1899,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
boolean alertAgain) {
final boolean wasHeadsUp = isHeadsUp(key);
if (wasHeadsUp) {
- mHeadsUpManager.updateNotification(entry, alertAgain);
if (!shouldInterrupt) {
// We don't want this to be interrupting anymore, lets remove it
mHeadsUpManager.removeNotification(key);
+ } else {
+ mHeadsUpManager.updateNotification(entry, alertAgain);
}
} else if (shouldInterrupt && alertAgain) {
// This notification was updated to be a heads-up, show it!
@@ -1929,7 +1949,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
- public void escalateHeadsUp() {
+ public void maybeEscalateHeadsUp() {
TreeSet<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getSortedEntries();
for (HeadsUpManager.HeadsUpEntry entry : entries) {
final StatusBarNotification sbn = entry.entry.notification;
@@ -2358,13 +2378,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
// manually dismiss the volume panel when interacting with the nav bar
if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
- if (mVolumeComponent != null) {
- mVolumeComponent.dismissNow();
- }
+ dismissVolumeDialog();
}
checkBarModes();
}
+ private void dismissVolumeDialog() {
+ if (mVolumeComponent != null) {
+ mVolumeComponent.dismissNow();
+ }
+ }
+
private void resumeSuspendedAutohide() {
if (mAutohideSuspended) {
scheduleAutohide();
@@ -2852,6 +2876,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
} catch (RemoteException e) {
// Ignore.
}
+ setNotificationsShown(newlyVisibleAr);
}
// State logging
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index fb42ba1..0e8e844 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -224,14 +224,14 @@ public class PhoneStatusBarPolicy {
} else if (mZen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
zenVisible = true;
zenIconId = R.drawable.stat_sys_zen_none;
- zenDescription = mContext.getString(R.string.zen_no_interruptions);
+ zenDescription = mContext.getString(R.string.interruption_level_none);
} else if (mZen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
zenVisible = true;
zenIconId = R.drawable.stat_sys_zen_important;
- zenDescription = mContext.getString(R.string.zen_important_interruptions);
+ zenDescription = mContext.getString(R.string.interruption_level_priority);
}
- if (DndTile.isVisible(mContext)
+ if (DndTile.isVisible(mContext) && !DndTile.isCombinedIcon(mContext)
&& audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
volumeVisible = true;
volumeIconId = R.drawable.stat_sys_ringer_silent;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index e701783..e6edbea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -80,7 +80,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
private float mCurrentInFrontAlpha;
private float mCurrentBehindAlpha;
private float mCurrentHeadsUpAlpha = 1;
- private int mAmountOfPinnedHeadsUps;
+ private int mPinnedHeadsUpCount;
private float mTopHeadsUpDragAmount;
private View mDraggedHeadsUpView;
@@ -347,25 +347,27 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
@Override
- public void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly) {
+ public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
}
@Override
- public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
- if (isHeadsUp) {
- mAmountOfPinnedHeadsUps++;
- } else {
- mAmountOfPinnedHeadsUps--;
- if (headsUp == mDraggedHeadsUpView) {
- mDraggedHeadsUpView = null;
- mTopHeadsUpDragAmount = 0.0f;
- }
+ public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
+ mPinnedHeadsUpCount++;
+ updateHeadsUpScrim(true);
+ }
+
+ @Override
+ public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
+ mPinnedHeadsUpCount--;
+ if (headsUp == mDraggedHeadsUpView) {
+ mDraggedHeadsUpView = null;
+ mTopHeadsUpDragAmount = 0.0f;
}
updateHeadsUpScrim(true);
}
@Override
- public void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
+ public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
}
private void updateHeadsUpScrim(boolean animate) {
@@ -374,12 +376,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
TAG_KEY_ANIM);
float animEndValue = -1;
if (previousAnimator != null) {
- if ((animate || alpha == mCurrentHeadsUpAlpha)) {
- // lets cancel any running animators
+ if (animate || alpha == mCurrentHeadsUpAlpha) {
previousAnimator.cancel();
}
- animEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
- TAG_HUN_START_ALPHA);
+ animEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim, TAG_HUN_START_ALPHA);
}
if (alpha != mCurrentHeadsUpAlpha && alpha != animEndValue) {
if (animate) {
@@ -390,7 +390,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
if (previousAnimator != null) {
float previousStartValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
TAG_HUN_START_ALPHA);
- float previousEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
+ float previousEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
TAG_HUN_END_ALPHA);
// we need to increase all animation keyframes of the previous animator by the
// relative change to the end value
@@ -410,6 +410,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
}
+ /**
+ * Set the amount the current top heads up view is dragged. The range is from 0 to 1 and 0 means
+ * the heads up is in its resting space and 1 means it's fully dragged out.
+ *
+ * @param draggedHeadsUpView the dragged view
+ * @param topHeadsUpDragAmount how far is it dragged
+ */
public void setTopHeadsUpDragAmount(View draggedHeadsUpView, float topHeadsUpDragAmount) {
mTopHeadsUpDragAmount = topHeadsUpDragAmount;
mDraggedHeadsUpView = draggedHeadsUpView;
@@ -417,9 +424,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
private float calculateHeadsUpAlpha() {
- if (mAmountOfPinnedHeadsUps >= 2) {
+ if (mPinnedHeadsUpCount >= 2) {
return 1.0f;
- } else if (mAmountOfPinnedHeadsUps == 0) {
+ } else if (mPinnedHeadsUpCount == 0) {
return 0.0f;
} else {
return 1.0f - mTopHeadsUpDragAmount;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
index 4a43c47..45c8938 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
@@ -27,6 +27,7 @@ import android.provider.MediaStore;
import android.util.Log;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
import java.util.HashMap;
import java.util.List;
@@ -228,7 +229,7 @@ public class SecureCameraLaunchManager {
// Get the list of applications that can handle the intent.
final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
- intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
+ intent, PackageManager.MATCH_DEFAULT_ONLY, KeyguardUpdateMonitor.getCurrentUser());
if (appList.size() == 0) {
if (DEBUG) Log.d(TAG, "No targets found for secure camera intent");
return false;
@@ -237,7 +238,7 @@ public class SecureCameraLaunchManager {
// Get the application that the intent resolves to.
ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
if (resolved == null || resolved.activityInfo == null) {
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index 65cd268..66d71f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -80,8 +80,8 @@ public class UnlockMethodCache {
}
private void update(boolean updateAlways) {
- int user = mLockPatternUtils.getCurrentUser();
- boolean secure = mLockPatternUtils.isSecure();
+ int user = KeyguardUpdateMonitor.getCurrentUser();
+ boolean secure = mLockPatternUtils.isSecure(user);
boolean currentlyInsecure = !secure || mKeyguardUpdateMonitor.getUserHasTrust(user);
boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index b4e4773..0db9221 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,11 +35,16 @@ import com.android.systemui.statusbar.phone.PhoneStatusBar;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Stack;
import java.util.TreeSet;
+/**
+ * A manager which handles heads up notifications which is a special mode where
+ * they simply peek from the top of the screen.
+ */
public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsListener {
private static final String TAG = "HeadsUpManager";
private static final boolean DEBUG = false;
@@ -48,7 +53,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
private final int mHeadsUpNotificationDecay;
private final int mMinimumDisplayTime;
- private final int mTouchSensitivityDelay;
+ private final int mTouchAcceptanceDelay;
private final ArrayMap<String, Long> mSnoozedPackages;
private final HashSet<OnHeadsUpChangedListener> mListeners = new HashSet<>();
private final int mDefaultSnoozeLengthMs;
@@ -67,13 +72,12 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
@Override
public boolean release(HeadsUpEntry instance) {
- instance.removeAutoCancelCallbacks();
+ instance.reset();
mPoolObjects.push(instance);
return true;
}
};
-
private PhoneStatusBar mBar;
private int mSnoozeLengthMs;
private ContentObserver mSettingsObserver;
@@ -86,13 +90,12 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
private boolean mTrackingHeadsUp;
private HashSet<NotificationData.Entry> mEntriesToRemoveAfterExpand = new HashSet<>();
private boolean mIsExpanded;
- private boolean mHasPinnedHeadsUp;
+ private boolean mHasPinnedNotification;
private int[] mTmpTwoArray = new int[2];
public HeadsUpManager(final Context context, ViewTreeObserver observer) {
Resources resources = context.getResources();
- mTouchSensitivityDelay = resources.getInteger(R.integer.heads_up_sensitivity_delay);
- if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay);
+ mTouchAcceptanceDelay = resources.getInteger(R.integer.touch_acceptance_delay);
mSnoozedPackages = new ArrayMap<>();
mDefaultSnoozeLengthMs = resources.getInteger(R.integer.heads_up_default_snooze_length_ms);
mSnoozeLengthMs = mDefaultSnoozeLengthMs;
@@ -116,7 +119,6 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
context.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(SETTING_HEADS_UP_SNOOZE_LENGTH_MS), false,
mSettingsObserver);
- if (DEBUG) Log.v(TAG, "mSnoozeLengthMs = " + mSnoozeLengthMs);
observer.addOnComputeInternalInsetsListener(this);
}
@@ -154,7 +156,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
if (alert) {
HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key);
headsUpEntry.updateEntry();
- setEntryToShade(headsUpEntry, mIsExpanded, false /* justAdded */, false);
+ setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */);
}
}
@@ -165,22 +167,23 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
headsUpEntry.setEntry(entry);
mHeadsUpEntries.put(entry.key, headsUpEntry);
entry.row.setHeadsUp(true);
- setEntryToShade(headsUpEntry, mIsExpanded /* inShade */, true /* justAdded */, false);
+ setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */);
for (OnHeadsUpChangedListener listener : mListeners) {
- listener.OnHeadsUpStateChanged(entry, true);
+ listener.onHeadsUpStateChanged(entry, true);
}
entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
}
- private void setEntryToShade(HeadsUpEntry headsUpEntry, boolean inShade, boolean justAdded,
- boolean forceImmediate) {
+ private void setEntryPinned(HeadsUpEntry headsUpEntry, boolean isPinned) {
ExpandableNotificationRow row = headsUpEntry.entry.row;
- if (row.isInShade() != inShade || justAdded) {
- row.setInShade(inShade);
- if (!justAdded || !inShade) {
- updatePinnedHeadsUpState(forceImmediate);
- for (OnHeadsUpChangedListener listener : mListeners) {
- listener.OnHeadsUpPinnedChanged(row, !inShade);
+ if (row.isPinned() != isPinned) {
+ row.setPinned(isPinned);
+ updatePinnedMode();
+ for (OnHeadsUpChangedListener listener : mListeners) {
+ if (isPinned) {
+ listener.onHeadsUpPinned(row);
+ } else {
+ listener.onHeadsUpUnPinned(row);
}
}
}
@@ -189,24 +192,23 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
private void removeHeadsUpEntry(NotificationData.Entry entry) {
HeadsUpEntry remove = mHeadsUpEntries.remove(entry.key);
mSortedEntries.remove(remove);
- mEntryPool.release(remove);
entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
entry.row.setHeadsUp(false);
- setEntryToShade(remove, true /* inShade */, false /* justAdded */,
- false /* forceImmediate */);
+ setEntryPinned(remove, false /* isPinned */);
for (OnHeadsUpChangedListener listener : mListeners) {
- listener.OnHeadsUpStateChanged(entry, false);
+ listener.onHeadsUpStateChanged(entry, false);
}
+ mEntryPool.release(remove);
}
- private void updatePinnedHeadsUpState(boolean forceImmediate) {
- boolean hasPinnedHeadsUp = hasPinnedHeadsUpInternal();
- if (hasPinnedHeadsUp == mHasPinnedHeadsUp) {
+ private void updatePinnedMode() {
+ boolean hasPinnedNotification = hasPinnedNotificationInternal();
+ if (hasPinnedNotification == mHasPinnedNotification) {
return;
}
- mHasPinnedHeadsUp = hasPinnedHeadsUp;
- for (OnHeadsUpChangedListener listener :mListeners) {
- listener.OnPinnedHeadsUpExistChanged(hasPinnedHeadsUp, forceImmediate);
+ mHasPinnedNotification = hasPinnedNotification;
+ for (OnHeadsUpChangedListener listener : mListeners) {
+ listener.onHeadsUpPinnedModeChanged(hasPinnedNotification);
}
}
@@ -222,7 +224,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
releaseImmediately(key);
return true;
} else {
- getHeadsUpEntry(key).hideAsSoonAsPossible();
+ getHeadsUpEntry(key).removeAsSoonAsPossible();
return false;
}
}
@@ -245,14 +247,13 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
return mHeadsUpEntries.containsKey(key);
}
-
/**
* Push any current Heads Up notification down into the shade.
*/
public void releaseAllImmediately() {
if (DEBUG) Log.v(TAG, "releaseAllImmediately");
- HashSet<String> keys = new HashSet<>(mHeadsUpEntries.keySet());
- for (String key: keys) {
+ ArrayList<String> keys = new ArrayList<>(mHeadsUpEntries.keySet());
+ for (String key : keys) {
releaseImmediately(key);
}
}
@@ -280,7 +281,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
}
public void snooze() {
- for (String key: mHeadsUpEntries.keySet()) {
+ for (String key : mHeadsUpEntries.keySet()) {
HeadsUpEntry entry = mHeadsUpEntries.get(key);
String packageName = entry.entry.notification.getPackageName();
mSnoozedPackages.put(snoozeKey(packageName, mUser),
@@ -310,8 +311,11 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
}
/**
+ * Decides whether a click is invalid for a notification, i.e it has not been shown long enough
+ * that a user might have consciously clicked on it.
+ *
* @param key the key of the touched notification
- * @return whether the touch is valid and should not be discarded
+ * @return whether the touch is invalid and should be discarded
*/
public boolean shouldSwallowClick(String key) {
HeadsUpEntry entry = mHeadsUpEntries.get(key);
@@ -322,14 +326,14 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
}
public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
- if (!mIsExpanded && mHasPinnedHeadsUp) {
+ if (!mIsExpanded && mHasPinnedNotification) {
int minX = Integer.MAX_VALUE;
int maxX = 0;
int minY = Integer.MAX_VALUE;
int maxY = 0;
- for (HeadsUpEntry entry: mSortedEntries) {
+ for (HeadsUpEntry entry : mSortedEntries) {
ExpandableNotificationRow row = entry.entry.row;
- if (!row.isInShade()) {
+ if (row.isPinned()) {
row.getLocationOnScreen(mTmpTwoArray);
minX = Math.min(minX, mTmpTwoArray[0]);
minY = Math.min(minY, 0);
@@ -349,7 +353,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("HeadsUpManager state:");
- pw.print(" mTouchSensitivityDelay="); pw.println(mTouchSensitivityDelay);
+ pw.print(" mTouchAcceptanceDelay="); pw.println(mTouchAcceptanceDelay);
pw.print(" mSnoozeLengthMs="); pw.println(mSnoozeLengthMs);
pw.print(" now="); pw.println(SystemClock.elapsedRealtime());
pw.print(" mUser="); pw.println(mUser);
@@ -365,38 +369,32 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
}
public boolean hasPinnedHeadsUp() {
- return mHasPinnedHeadsUp;
+ return mHasPinnedNotification;
}
- private boolean hasPinnedHeadsUpInternal() {
- for (String key: mHeadsUpEntries.keySet()) {
+ private boolean hasPinnedNotificationInternal() {
+ for (String key : mHeadsUpEntries.keySet()) {
HeadsUpEntry entry = mHeadsUpEntries.get(key);
- if (!entry.entry.row.isInShade()) {
+ if (entry.entry.row.isPinned()) {
return true;
}
}
return false;
}
- public void addSwipedOutKey(String key) {
+ /**
+ * Notifies that a notification was swiped out and will be removed.
+ *
+ * @param key the notification key
+ */
+ public void addSwipedOutNotification(String key) {
mSwipedOutKeys.add(key);
}
- public float getHighestPinnedHeadsUp() {
- float max = 0;
- for (HeadsUpEntry entry: mSortedEntries) {
- if (!entry.entry.row.isInShade()) {
- max = Math.max(max, entry.entry.row.getActualHeight());
- }
- }
- return max;
- }
-
- public void releaseAllToShade() {
- for (String key: mHeadsUpEntries.keySet()) {
+ public void unpinAll() {
+ for (String key : mHeadsUpEntries.keySet()) {
HeadsUpEntry entry = mHeadsUpEntries.get(key);
- setEntryToShade(entry, true /* toShade */, false /* justAdded */,
- true /* forceImmediate */);
+ setEntryPinned(entry, false /* isPinned */);
}
}
@@ -420,7 +418,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
if (isExpanded != mIsExpanded) {
mIsExpanded = isExpanded;
if (isExpanded) {
- releaseAllToShade();
+ unpinAll();
}
}
}
@@ -430,6 +428,12 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
return topEntry != null ? topEntry.entry.row.getHeadsUpHeight() : 0;
}
+ /**
+ * Compare two entries and decide how they should be ranked.
+ *
+ * @return -1 if the first argument should be ranked higher than the second, 1 if the second
+ * one should be ranked higher and 0 if they are equal.
+ */
public int compare(NotificationData.Entry a, NotificationData.Entry b) {
HeadsUpEntry aEntry = getHeadsUpEntry(a.key);
HeadsUpEntry bEntry = getHeadsUpEntry(b.key);
@@ -439,6 +443,11 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
return aEntry.compareTo(bEntry);
}
+
+ /**
+ * This represents a notification and how long it is in a heads up mode. It also manages its
+ * lifecycle automatically when created.
+ */
public class HeadsUpEntry implements Comparable<HeadsUpEntry> {
public NotificationData.Entry entry;
public long postTime;
@@ -449,7 +458,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
this.entry = entry;
// The actual post time will be just after the heads-up really slided in
- postTime = mClock.currentTimeMillis() + mTouchSensitivityDelay;
+ postTime = mClock.currentTimeMillis() + mTouchAcceptanceDelay;
mRemoveHeadsUpRunnable = new Runnable() {
@Override
public void run() {
@@ -467,7 +476,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
long currentTime = mClock.currentTimeMillis();
earliestRemovaltime = currentTime + mMinimumDisplayTime;
postTime = Math.max(postTime, currentTime);
- removeAutoCancelCallbacks();
+ removeAutoRemovalCallbacks();
if (canEntryDecay()) {
long finishTime = postTime + mHeadsUpNotificationDecay;
long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
@@ -487,7 +496,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
: -1;
}
- public void removeAutoCancelCallbacks() {
+ public void removeAutoRemovalCallbacks() {
mHandler.removeCallbacks(mRemoveHeadsUpRunnable);
}
@@ -495,11 +504,17 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
return earliestRemovaltime < mClock.currentTimeMillis();
}
- public void hideAsSoonAsPossible() {
- removeAutoCancelCallbacks();
+ public void removeAsSoonAsPossible() {
+ removeAutoRemovalCallbacks();
mHandler.postDelayed(mRemoveHeadsUpRunnable,
earliestRemovaltime - mClock.currentTimeMillis());
}
+
+ public void reset() {
+ removeAutoRemovalCallbacks();
+ entry = null;
+ mRemoveHeadsUpRunnable = null;
+ }
}
/**
@@ -519,8 +534,29 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
}
public interface OnHeadsUpChangedListener {
- void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly);
- void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp);
- void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp);
+ /**
+ * The state whether there exist pinned heads-ups or not changed.
+ *
+ * @param inPinnedMode whether there are any pinned heads-ups
+ */
+ void onHeadsUpPinnedModeChanged(boolean inPinnedMode);
+
+ /**
+ * A notification was just pinned to the top.
+ */
+ void onHeadsUpPinned(ExpandableNotificationRow headsUp);
+
+ /**
+ * A notification was just unpinned from the top.
+ */
+ void onHeadsUpUnPinned(ExpandableNotificationRow headsUp);
+
+ /**
+ * A notification just became a heads up or turned back to its normal state.
+ *
+ * @param entry the entry of the changed notification
+ * @param isHeadsUp whether the notification is now a headsUp notification
+ */
+ void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
index 0dce82f..5d89e2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
@@ -26,6 +26,7 @@ import android.view.LayoutInflater;
import android.view.View;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.statusbar.phone.KeyguardPreviewContainer;
import java.util.List;
@@ -80,13 +81,13 @@ public class PreviewInflater {
WidgetInfo info = new WidgetInfo();
PackageManager packageManager = mContext.getPackageManager();
final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
- intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
+ intent, PackageManager.MATCH_DEFAULT_ONLY, KeyguardUpdateMonitor.getCurrentUser());
if (appList.size() == 0) {
return null;
}
ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
if (wouldLaunchResolverActivity(resolved, appList)) {
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
index 67cc788..9d84a85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
@@ -35,6 +35,7 @@ public interface ZenModeController {
boolean isZenAvailable();
ComponentName getEffectsSuppressor();
boolean isCountdownConditionSupported();
+ int getCurrentUser();
public static class Callback {
public void onZenChanged(int zen) {}
@@ -45,4 +46,5 @@ public interface ZenModeController {
public void onManualRuleChanged(ZenRule rule) {}
public void onConfigChanged(ZenModeConfig config) {}
}
+
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 830a197..5b80ac2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.policy;
+import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
@@ -159,6 +160,11 @@ public class ZenModeControllerImpl implements ZenModeController {
.isSystemConditionProviderEnabled(ZenModeConfig.COUNTDOWN_PATH);
}
+ @Override
+ public int getCurrentUser() {
+ return ActivityManager.getCurrentUser();
+ }
+
private void fireNextAlarmChanged() {
for (Callback cb : mCallbacks) {
cb.onNextAlarmChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java
new file mode 100644
index 0000000..05c0099
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.stack;
+
+import android.graphics.Path;
+import android.view.animation.PathInterpolator;
+
+/**
+ * An interpolator specifically designed for the appear animation of heads up notifications.
+ */
+public class HeadsUpAppearInterpolator extends PathInterpolator {
+ public HeadsUpAppearInterpolator() {
+ super(getAppearPath());
+ }
+
+ private static Path getAppearPath() {
+ Path path = new Path();
+ path.moveTo(0, 0);
+ float x1 = 250f;
+ float x2 = 150f;
+ float x3 = 100f;
+ float y1 = 90f;
+ float y2 = 78f;
+ float y3 = 80f;
+ float xTot = (x1 + x2 + x3);
+ path.cubicTo(x1 * 0.9f / xTot, 0f,
+ x1 * 0.8f / xTot, y1 / y3,
+ x1 / xTot , y1 / y3);
+ path.cubicTo((x1 + x2 * 0.4f) / xTot, y1 / y3,
+ (x1 + x2 * 0.2f) / xTot, y2 / y3,
+ (x1 + x2) / xTot, y2 / y3);
+ path.cubicTo((x1 + x2 + x3 * 0.4f) / xTot, y2 / y3,
+ (x1 + x2 + x3 * 0.2f) / xTot, 1f,
+ 1f, 1f);
+ return path;
+ }
+}
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 88fc602..a1b0cae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -204,7 +204,6 @@ public class NotificationStackScrollLayout extends ViewGroup
private ViewGroup mScrollView;
private boolean mInterceptDelegateEnabled;
private boolean mDelegateToScrollView;
-
private boolean mDisallowScrollingInThisMotion;
private long mGoToFullShadeDelay;
private ViewTreeObserver.OnPreDrawListener mChildrenUpdater
@@ -487,9 +486,9 @@ public class NotificationStackScrollLayout extends ViewGroup
int stackHeight;
float paddingOffset;
boolean trackingHeadsUp = mTrackingHeadsUp;
- int normalExpandPositionStart = trackingHeadsUp ? mHeadsUpManager.getTopHeadsUpHeight()
+ int normalUnfoldPositionStart = trackingHeadsUp ? mHeadsUpManager.getTopHeadsUpHeight()
: minStackHeight;
- if (newStackHeight - mTopPadding - mTopPaddingOverflow >= normalExpandPositionStart
+ if (newStackHeight - mTopPadding - mTopPaddingOverflow >= normalUnfoldPositionStart
|| getNotGoneChildCount() == 0) {
paddingOffset = mTopPaddingOverflow;
stackHeight = newStackHeight;
@@ -582,7 +581,7 @@ public class NotificationStackScrollLayout extends ViewGroup
if (v instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) v;
if (row.isHeadsUp()) {
- mHeadsUpManager.addSwipedOutKey(row.getStatusBarNotification().getKey());
+ mHeadsUpManager.addSwipedOutNotification(row.getStatusBarNotification().getKey());
}
}
final View veto = v.findViewById(R.id.veto);
@@ -626,10 +625,10 @@ public class NotificationStackScrollLayout extends ViewGroup
requestChildrenUpdate();
}
- public boolean isPinnedHeadsUp(View v) {
+ public static boolean isPinnedHeadsUp(View v) {
if (v instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) v;
- return row.isHeadsUp() && !row.isInShade();
+ return row.isHeadsUp() && row.isPinned();
}
return false;
}
@@ -711,7 +710,7 @@ public class NotificationStackScrollLayout extends ViewGroup
if (touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
if (slidingChild instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) slidingChild;
- if (row.isHeadsUp() && !row.isInShade()
+ if (row.isHeadsUp() && row.isPinned()
&& mHeadsUpManager.getTopEntry().entry.row != row) {
continue;
}
@@ -812,7 +811,8 @@ public class NotificationStackScrollLayout extends ViewGroup
}
handleEmptySpaceClick(ev);
boolean expandWantsIt = false;
- if (!mSwipingInProgress && !mOnlyScrollingInThisMotion && isScrollingEnabled()) {
+ if (mIsExpanded && !mSwipingInProgress && !mOnlyScrollingInThisMotion
+ && isScrollingEnabled()) {
if (isCancelOrUp) {
mExpandHelper.onlyObserveMovements(false);
}
@@ -824,7 +824,8 @@ public class NotificationStackScrollLayout extends ViewGroup
}
}
boolean scrollerWantsIt = false;
- if (!mSwipingInProgress && !mExpandingNotification && !mDisallowScrollingInThisMotion) {
+ if (mIsExpanded && !mSwipingInProgress && !mExpandingNotification
+ && !mDisallowScrollingInThisMotion) {
scrollerWantsIt = onScrollTouch(ev);
}
boolean horizontalSwipeWantsIt = false;
@@ -1872,15 +1873,15 @@ public class NotificationStackScrollLayout extends ViewGroup
boolean onBottom = false;
if (!mIsExpanded && !isHeadsUp) {
type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
- } else if (mAddedHeadsUpChildren.contains(row) || (!row.isInShade() && !mIsExpanded)) {
- if (!row.isInShade() || shouldHunAppearFromBottom(row)) {
+ } else if (mAddedHeadsUpChildren.contains(row) || (row.isPinned() && !mIsExpanded)) {
+ if (row.isPinned() || shouldHunAppearFromBottom(row)) {
// Our custom add animation
type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR;
} else {
// Normal add animation
type = AnimationEvent.ANIMATION_TYPE_ADD;
}
- onBottom = row.isInShade();
+ onBottom = !row.isPinned();
}
AnimationEvent event = new AnimationEvent(row, type);
event.headsUpFromBottom = onBottom;
@@ -2670,7 +2671,7 @@ public class NotificationStackScrollLayout extends ViewGroup
}
}
- public void performOnAnimationFinished(Runnable runnable) {
+ public void runAfterAnimationFinished(Runnable runnable) {
mAnimationFinishedRunnables.add(runnable);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 2a49a4c..202063a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -311,7 +311,8 @@ public class StackScrollAlgorithm {
StackViewState viewState = resultState.getViewStateForView(
nextChild);
// The child below the dragged one must be fully visible
- if (!isPinnedHeadsUpView(draggedView) || isPinnedHeadsUpView(nextChild)) {
+ if (!NotificationStackScrollLayout.isPinnedHeadsUp(draggedView)
+ || NotificationStackScrollLayout.isPinnedHeadsUp(nextChild)) {
viewState.alpha = 1;
}
}
@@ -324,14 +325,6 @@ public class StackScrollAlgorithm {
}
}
- private boolean isPinnedHeadsUpView(View view) {
- if (view instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) view;
- return row.isHeadsUp() && !row.isInShade();
- }
- return false;
- }
-
/**
* Update the visible children on the state.
*/
@@ -380,7 +373,7 @@ public class StackScrollAlgorithm {
/**
* Determine the positions for the views. This is the main part of the algorithm.
*
- * @param resultState The result state to update if a change to the properties of a child occurs
+ * @param resultState The result state to update if a change to the properties of a child occurs
* @param algorithmState The state in which the current pass of the algorithm is currently in
* @param ambientState The current ambient state
*/
@@ -515,11 +508,12 @@ public class StackScrollAlgorithm {
}
StackViewState childState = resultState.getViewStateForView(row);
boolean isTopEntry = topHeadsUpEntry == row;
- if (!row.isInShade()) {
+ if (row.isPinned()) {
childState.yTranslation = 0;
childState.height = row.getHeadsUpHeight();
if (!isTopEntry) {
- // Ensure that a headsUp is never below the topmost headsUp
+ // Ensure that a headsUp doesn't vertically extend further than the heads-up at
+ // the top most z-position
StackViewState topState = resultState.getViewStateForView(topHeadsUpEntry);
childState.height = row.getHeadsUpHeight();
childState.yTranslation = topState.yTranslation + topState.height
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index f5d94c8..b9466d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -21,11 +21,9 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
-import android.graphics.Path;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -78,6 +76,7 @@ public class StackStateAnimator {
private final Interpolator mFastOutSlowInInterpolator;
private final Interpolator mHeadsUpAppearInterpolator;
private final int mGoToFullShadeAppearingTranslation;
+ private final StackViewState mTmpState = new StackViewState();
public NotificationStackScrollLayout mHostLayout;
private ArrayList<NotificationStackScrollLayout.AnimationEvent> mNewEvents =
new ArrayList<>();
@@ -95,7 +94,6 @@ public class StackStateAnimator {
private ValueAnimator mTopOverScrollAnimator;
private ValueAnimator mBottomOverScrollAnimator;
private ExpandableNotificationRow mChildExpandingView;
- private StackViewState mTmpState = new StackViewState();
private int mHeadsUpAppearHeightBottom;
private boolean mShadeExpanded;
@@ -106,25 +104,7 @@ public class StackStateAnimator {
mGoToFullShadeAppearingTranslation =
hostLayout.getContext().getResources().getDimensionPixelSize(
R.dimen.go_to_full_shade_appearing_translation);
- Path path = new Path();
- path.moveTo(0, 0);
- float x1 = 250f;
- float x2 = 150f;
- float x3 = 100f;
- float y1 = 90f;
- float y2 = 78f;
- float y3 = 80f;
- float xTot = (x1 + x2 + x3);
- path.cubicTo(x1 * 0.9f / xTot, 0f,
- x1 * 0.8f / xTot, y1 / y3,
- x1 / xTot , y1 / y3);
- path.cubicTo((x1 + x2 * 0.4f) / xTot, y1 / y3,
- (x1 + x2 * 0.2f) / xTot, y2 / y3,
- (x1 + x2) / xTot, y2 / y3);
- path.cubicTo((x1 + x2 + x3 * 0.4f) / xTot, y2 / y3,
- (x1 + x2 + x3 * 0.2f) / xTot, 1f,
- 1f, 1f);
- mHeadsUpAppearInterpolator = new PathInterpolator(path);
+ mHeadsUpAppearInterpolator = new HeadsUpAppearInterpolator();
}
public boolean isRunning() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index dda40d3..a5684a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -121,7 +121,7 @@ public class TvStatusBar extends BaseStatusBar {
}
@Override
- public void escalateHeadsUp() {
+ public void maybeEscalateHeadsUp() {
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 240c210..e6c95b5 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -24,12 +24,20 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.MoveCallback;
+import android.os.Bundle;
+import android.os.Handler;
import android.os.UserHandle;
import android.os.storage.DiskInfo;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
import android.util.Log;
+import android.util.SparseArray;
import com.android.internal.R;
import com.android.systemui.SystemUI;
@@ -39,39 +47,93 @@ import java.util.List;
public class StorageNotification extends SystemUI {
private static final String TAG = "StorageNotification";
- private static final int NOTIF_ID = 0x53544f52; // STOR
+ private static final int PUBLIC_ID = 0x53505542; // SPUB
+ private static final int PRIVATE_ID = 0x53505256; // SPRV
+ private static final int DISK_ID = 0x5344534b; // SDSK
+ private static final int MOVE_ID = 0x534d4f56; // SMOV
private static final String ACTION_SNOOZE_VOLUME = "com.android.systemui.action.SNOOZE_VOLUME";
// TODO: delay some notifications to avoid bumpy fast operations
- // TODO: annoy user when private media is missing
private NotificationManager mNotificationManager;
private StorageManager mStorageManager;
+ private static class MoveInfo {
+ public int moveId;
+ public Bundle extras;
+ public String packageName;
+ public String label;
+ public String volumeUuid;
+ }
+
+ private final SparseArray<MoveInfo> mMoves = new SparseArray<>();
+
private final StorageEventListener mListener = new StorageEventListener() {
@Override
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
- onVolumeStateChangedInternal(vol, oldState, newState);
+ onVolumeStateChangedInternal(vol);
}
@Override
- public void onVolumeMetadataChanged(VolumeInfo vol) {
+ public void onVolumeRecordChanged(VolumeRecord rec) {
// Avoid kicking notifications when getting early metadata before
// mounted. If already mounted, we're being kicked because of a
// nickname or init'ed change.
- if (vol.isMountedReadable()) {
- onVolumeStateChangedInternal(vol, vol.getState(), vol.getState());
+ final VolumeInfo vol = mStorageManager.findVolumeByUuid(rec.getFsUuid());
+ if (vol != null && vol.isMountedReadable()) {
+ onVolumeStateChangedInternal(vol);
}
}
+
+ @Override
+ public void onVolumeForgotten(String fsUuid) {
+ // Stop annoying the user
+ mNotificationManager.cancelAsUser(fsUuid, PRIVATE_ID, UserHandle.ALL);
+ }
+
+ @Override
+ public void onDiskScanned(DiskInfo disk, int volumeCount) {
+ onDiskScannedInternal(disk, volumeCount);
+ }
};
private final BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: kick this onto background thread
- final String volId = intent.getStringExtra(VolumeInfo.EXTRA_VOLUME_ID);
- mStorageManager.setVolumeSnoozed(volId, true);
+ final String fsUuid = intent.getStringExtra(VolumeRecord.EXTRA_FS_UUID);
+ mStorageManager.setVolumeSnoozed(fsUuid, true);
+ }
+ };
+
+ private final MoveCallback mMoveCallback = new MoveCallback() {
+ @Override
+ public void onCreated(int moveId, Bundle extras) {
+ final MoveInfo move = new MoveInfo();
+ move.moveId = moveId;
+ move.extras = extras;
+ if (extras != null) {
+ move.packageName = extras.getString(Intent.EXTRA_PACKAGE_NAME);
+ move.label = extras.getString(Intent.EXTRA_TITLE);
+ move.volumeUuid = extras.getString(VolumeRecord.EXTRA_FS_UUID);
+ }
+ mMoves.put(moveId, move);
+ }
+
+ @Override
+ public void onStatusChanged(int moveId, int status, long estMillis) {
+ final MoveInfo move = mMoves.get(moveId);
+ if (move == null) {
+ Log.w(TAG, "Ignoring unknown move " + moveId);
+ return;
+ }
+
+ if (PackageManager.isMoveStatusFinished(status)) {
+ onMoveFinished(move, status);
+ } else {
+ onMoveProgress(move, status, estMillis);
+ }
}
};
@@ -88,20 +150,99 @@ public class StorageNotification extends SystemUI {
// Kick current state into place
final List<VolumeInfo> vols = mStorageManager.getVolumes();
for (VolumeInfo vol : vols) {
- onVolumeStateChangedInternal(vol, vol.getState(), vol.getState());
+ onVolumeStateChangedInternal(vol);
}
+
+ mContext.getPackageManager().registerMoveCallback(mMoveCallback, new Handler());
+
+ updateMissingPrivateVolumes();
}
- public void onVolumeStateChangedInternal(VolumeInfo vol, int oldState, int newState) {
- // We only care about public volumes
- if (vol.getType() != VolumeInfo.TYPE_PUBLIC) {
- return;
+ private void updateMissingPrivateVolumes() {
+ final List<VolumeRecord> recs = mStorageManager.getVolumeRecords();
+ for (VolumeRecord rec : recs) {
+ if (rec.getType() != VolumeInfo.TYPE_PRIVATE) continue;
+
+ final String fsUuid = rec.getFsUuid();
+ final VolumeInfo info = mStorageManager.findVolumeByUuid(fsUuid);
+ if (info != null && info.isMountedWritable()) {
+ // Yay, private volume is here!
+ mNotificationManager.cancelAsUser(fsUuid, PRIVATE_ID, UserHandle.ALL);
+
+ } else {
+ // Boo, annoy the user to reinsert the private volume
+ final CharSequence title = mContext.getString(R.string.ext_media_missing_title,
+ rec.getNickname());
+ final CharSequence text = mContext.getString(R.string.ext_media_missing_message);
+
+ final Notification notif = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.stat_notify_sdcard)
+ .setColor(mContext.getColor(R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(buildForgetPendingIntent(rec))
+ .setStyle(new Notification.BigTextStyle().bigText(text))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setLocalOnly(true)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setOngoing(true)
+ .build();
+
+ mNotificationManager.notifyAsUser(fsUuid, PRIVATE_ID, notif, UserHandle.ALL);
+ }
}
+ }
+
+ private void onDiskScannedInternal(DiskInfo disk, int volumeCount) {
+ if (volumeCount == 0) {
+ // No supported volumes found, give user option to format
+ final CharSequence title = mContext.getString(
+ R.string.ext_media_unmountable_notification_title, disk.getDescription());
+ final CharSequence text = mContext.getString(
+ R.string.ext_media_unmountable_notification_message, disk.getDescription());
+
+ final Notification notif = new Notification.Builder(mContext)
+ .setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE))
+ .setColor(mContext.getColor(R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(buildInitPendingIntent(disk))
+ .setStyle(new Notification.BigTextStyle().bigText(text))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setLocalOnly(true)
+ .setCategory(Notification.CATEGORY_ERROR)
+ .build();
- Log.d(TAG, vol.toString());
+ mNotificationManager.notifyAsUser(disk.getId(), DISK_ID, notif, UserHandle.ALL);
+
+ } else {
+ // Yay, we have volumes!
+ mNotificationManager.cancelAsUser(disk.getId(), DISK_ID, UserHandle.ALL);
+ }
+ }
+
+ private void onVolumeStateChangedInternal(VolumeInfo vol) {
+ switch (vol.getType()) {
+ case VolumeInfo.TYPE_PRIVATE:
+ onPrivateVolumeStateChangedInternal(vol);
+ break;
+ case VolumeInfo.TYPE_PUBLIC:
+ onPublicVolumeStateChangedInternal(vol);
+ break;
+ }
+ }
+
+ private void onPrivateVolumeStateChangedInternal(VolumeInfo vol) {
+ Log.d(TAG, "Notifying about private volume: " + vol.toString());
+
+ updateMissingPrivateVolumes();
+ }
+
+ private void onPublicVolumeStateChangedInternal(VolumeInfo vol) {
+ Log.d(TAG, "Notifying about public volume: " + vol.toString());
final Notification notif;
- switch (newState) {
+ switch (vol.getState()) {
case VolumeInfo.STATE_UNMOUNTED:
notif = onVolumeUnmounted(vol);
break;
@@ -133,9 +274,9 @@ public class StorageNotification extends SystemUI {
}
if (notif != null) {
- mNotificationManager.notifyAsUser(vol.getId(), NOTIF_ID, notif, UserHandle.ALL);
+ mNotificationManager.notifyAsUser(vol.getId(), PUBLIC_ID, notif, UserHandle.ALL);
} else {
- mNotificationManager.cancelAsUser(vol.getId(), NOTIF_ID, UserHandle.ALL);
+ mNotificationManager.cancelAsUser(vol.getId(), PUBLIC_ID, UserHandle.ALL);
}
}
@@ -159,20 +300,24 @@ public class StorageNotification extends SystemUI {
}
private Notification onVolumeMounted(VolumeInfo vol) {
+ final VolumeRecord rec = mStorageManager.findRecordByUuid(vol.getFsUuid());
+
// Don't annoy when user dismissed in past
- if (vol.isSnoozed()) return null;
+ if (rec.isSnoozed()) return null;
final DiskInfo disk = vol.getDisk();
- if (disk.isAdoptable() && !vol.isInited()) {
+ if (disk.isAdoptable() && !rec.isInited()) {
final CharSequence title = disk.getDescription();
final CharSequence text = mContext.getString(
R.string.ext_media_new_notification_message, disk.getDescription());
+ final PendingIntent initIntent = buildInitPendingIntent(vol);
return buildNotificationBuilder(vol, title, text)
.addAction(new Action(0, mContext.getString(R.string.ext_media_init_action),
- buildInitPendingIntent(vol)))
+ initIntent))
.addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
+ .setContentIntent(initIntent)
.setDeleteIntent(buildSnoozeIntent(vol))
.setCategory(Notification.CATEGORY_SYSTEM)
.build();
@@ -182,11 +327,13 @@ public class StorageNotification extends SystemUI {
final CharSequence text = mContext.getString(
R.string.ext_media_ready_notification_message, disk.getDescription());
+ final PendingIntent browseIntent = buildBrowsePendingIntent(vol);
return buildNotificationBuilder(vol, title, text)
.addAction(new Action(0, mContext.getString(R.string.ext_media_browse_action),
- buildBrowsePendingIntent(vol)))
+ browseIntent))
.addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
+ .setContentIntent(browseIntent)
.setDeleteIntent(buildSnoozeIntent(vol))
.setCategory(Notification.CATEGORY_SYSTEM)
.setPriority(Notification.PRIORITY_LOW)
@@ -221,7 +368,7 @@ public class StorageNotification extends SystemUI {
R.string.ext_media_unmountable_notification_message, disk.getDescription());
return buildNotificationBuilder(vol, title, text)
- .setContentIntent(buildDetailsPendingIntent(vol))
+ .setContentIntent(buildVolumeSettingsPendingIntent(vol))
.setCategory(Notification.CATEGORY_ERROR)
.build();
}
@@ -260,16 +407,102 @@ public class StorageNotification extends SystemUI {
.build();
}
- private int getSmallIcon(VolumeInfo vol) {
- if (vol.disk.isSd()) {
- switch (vol.getState()) {
+ private void onMoveProgress(MoveInfo move, int status, long estMillis) {
+ final CharSequence title;
+ if (!TextUtils.isEmpty(move.label)) {
+ title = mContext.getString(R.string.ext_media_move_specific_title, move.label);
+ } else {
+ title = mContext.getString(R.string.ext_media_move_title);
+ }
+
+ final CharSequence text;
+ if (estMillis < 0) {
+ text = null;
+ } else {
+ text = DateUtils.formatDuration(estMillis);
+ }
+
+ final PendingIntent intent;
+ if (move.packageName != null) {
+ intent = buildWizardMovePendingIntent(move);
+ } else {
+ intent = buildWizardMigratePendingIntent(move);
+ }
+
+ final Notification notif = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.stat_notify_sdcard)
+ .setColor(mContext.getColor(R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(intent)
+ .setStyle(new Notification.BigTextStyle().bigText(text))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setLocalOnly(true)
+ .setCategory(Notification.CATEGORY_PROGRESS)
+ .setPriority(Notification.PRIORITY_LOW)
+ .setProgress(100, status, false)
+ .setOngoing(true)
+ .build();
+
+ mNotificationManager.notifyAsUser(move.packageName, MOVE_ID, notif, UserHandle.ALL);
+ }
+
+ private void onMoveFinished(MoveInfo move, int status) {
+ if (move.packageName != null) {
+ // We currently ignore finished app moves; just clear the last
+ // published progress
+ mNotificationManager.cancelAsUser(move.packageName, MOVE_ID, UserHandle.ALL);
+ return;
+ }
+
+ final VolumeInfo privateVol = mContext.getPackageManager().getPrimaryStorageCurrentVolume();
+ final String descrip = mStorageManager.getBestVolumeDescription(privateVol);
+
+ final CharSequence title;
+ final CharSequence text;
+ if (status == PackageManager.MOVE_SUCCEEDED) {
+ title = mContext.getString(R.string.ext_media_move_success_title);
+ text = mContext.getString(R.string.ext_media_move_success_message, descrip);
+ } else {
+ title = mContext.getString(R.string.ext_media_move_failure_title);
+ text = mContext.getString(R.string.ext_media_move_failure_message);
+ }
+
+ // Jump back into the wizard flow if we moved to a real disk
+ final PendingIntent intent;
+ if (privateVol != null && privateVol.getDisk() != null) {
+ intent = buildWizardReadyPendingIntent(privateVol.getDisk());
+ } else {
+ intent = buildVolumeSettingsPendingIntent(privateVol);
+ }
+
+ final Notification notif = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.stat_notify_sdcard)
+ .setColor(mContext.getColor(R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(intent)
+ .setStyle(new Notification.BigTextStyle().bigText(text))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setLocalOnly(true)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setPriority(Notification.PRIORITY_LOW)
+ .setAutoCancel(true)
+ .build();
+
+ mNotificationManager.notifyAsUser(move.packageName, MOVE_ID, notif, UserHandle.ALL);
+ }
+
+ private int getSmallIcon(DiskInfo disk, int state) {
+ if (disk.isSd()) {
+ switch (state) {
case VolumeInfo.STATE_CHECKING:
case VolumeInfo.STATE_EJECTING:
return R.drawable.stat_notify_sdcard_prepare;
default:
return R.drawable.stat_notify_sdcard;
}
- } else if (vol.disk.isUsb()) {
+ } else if (disk.isUsb()) {
return R.drawable.stat_sys_data_usb;
} else {
return R.drawable.stat_notify_sdcard;
@@ -279,7 +512,7 @@ public class StorageNotification extends SystemUI {
private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title,
CharSequence text) {
return new Notification.Builder(mContext)
- .setSmallIcon(getSmallIcon(vol))
+ .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)
.setContentText(text)
@@ -288,6 +521,17 @@ public class StorageNotification extends SystemUI {
.setLocalOnly(true);
}
+ private PendingIntent buildInitPendingIntent(DiskInfo disk) {
+ final Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.deviceinfo.StorageWizardInit");
+ intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
+
+ final int requestKey = disk.getId().hashCode();
+ return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
+ PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+ }
+
private PendingIntent buildInitPendingIntent(VolumeInfo vol) {
final Intent intent = new Intent();
intent.setClassName("com.android.settings",
@@ -318,10 +562,20 @@ public class StorageNotification extends SystemUI {
PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
}
- private PendingIntent buildDetailsPendingIntent(VolumeInfo vol) {
+ private PendingIntent buildVolumeSettingsPendingIntent(VolumeInfo vol) {
final Intent intent = new Intent();
- intent.setClassName("com.android.settings",
- "com.android.settings.Settings$StorageVolumeSettingsActivity");
+ switch (vol.getType()) {
+ case VolumeInfo.TYPE_PRIVATE:
+ intent.setClassName("com.android.settings",
+ "com.android.settings.Settings$PrivateVolumeSettingsActivity");
+ break;
+ case VolumeInfo.TYPE_PUBLIC:
+ intent.setClassName("com.android.settings",
+ "com.android.settings.Settings$PublicVolumeSettingsActivity");
+ break;
+ default:
+ return null;
+ }
intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
final int requestKey = vol.getId().hashCode();
@@ -331,10 +585,55 @@ public class StorageNotification extends SystemUI {
private PendingIntent buildSnoozeIntent(VolumeInfo vol) {
final Intent intent = new Intent(ACTION_SNOOZE_VOLUME);
- intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
+ intent.putExtra(VolumeRecord.EXTRA_FS_UUID, vol.getFsUuid());
final int requestKey = vol.getId().hashCode();
return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
}
+
+ private PendingIntent buildForgetPendingIntent(VolumeRecord rec) {
+ final Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.Settings$PrivateVolumeForgetActivity");
+ intent.putExtra(VolumeRecord.EXTRA_FS_UUID, rec.getFsUuid());
+
+ final int requestKey = rec.getFsUuid().hashCode();
+ return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
+ PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+ }
+
+ private PendingIntent buildWizardMigratePendingIntent(MoveInfo move) {
+ final Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.deviceinfo.StorageWizardMigrateProgress");
+ intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
+
+ final VolumeInfo vol = mStorageManager.findVolumeByQualifiedUuid(move.volumeUuid);
+ intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
+
+ return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
+ PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+ }
+
+ private PendingIntent buildWizardMovePendingIntent(MoveInfo move) {
+ final Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.deviceinfo.StorageWizardMoveProgress");
+ intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
+
+ return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
+ PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+ }
+
+ private PendingIntent buildWizardReadyPendingIntent(DiskInfo disk) {
+ final Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.deviceinfo.StorageWizardReady");
+ intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
+
+ final int requestKey = disk.getId().hashCode();
+ return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
+ PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
index 4f20ac7..f7cb9fe 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
@@ -17,6 +17,7 @@
package com.android.systemui.volume;
import android.content.Context;
+import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -30,6 +31,8 @@ import java.util.Objects;
public class SegmentedButtons extends LinearLayout {
private static final int LABEL_RES_KEY = R.id.label;
+ private static final Typeface REGULAR = Typeface.create("sans-serif", Typeface.NORMAL);
+ private static final Typeface MEDIUM = Typeface.create("sans-serif-medium", Typeface.NORMAL);
private final Context mContext;
private final LayoutInflater mInflater;
@@ -60,6 +63,7 @@ public class SegmentedButtons extends LinearLayout {
final Object tag = c.getTag();
final boolean selected = Objects.equals(mSelectedValue, tag);
c.setSelected(selected);
+ c.setTypeface(selected ? MEDIUM : REGULAR);
}
fireOnSelected();
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Util.java b/packages/SystemUI/src/com/android/systemui/volume/Util.java
index 216a4da..4214091 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Util.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Util.java
@@ -144,9 +144,14 @@ class Util {
return HMMAA.format(new Date(millis));
}
- public static void setText(TextView tv, CharSequence text) {
- if (Objects.equals(tv.getText(), text)) return;
+ private static CharSequence emptyToNull(CharSequence str) {
+ return str == null || str.length() == 0 ? null : str;
+ }
+
+ public static boolean setText(TextView tv, CharSequence text) {
+ if (Objects.equals(emptyToNull(tv.getText()), emptyToNull(text))) return false;
tv.setText(text);
+ return true;
}
public static final void setVisOrGone(View v, boolean vis) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index bb4aa61..9434036 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -37,7 +37,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings.Global;
-import android.service.notification.ZenModeConfig;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseBooleanArray;
@@ -52,7 +51,6 @@ import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
-import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
@@ -90,16 +88,12 @@ public class VolumeDialog {
private final ViewGroup mDialogView;
private final ViewGroup mDialogContentView;
private final ImageButton mExpandButton;
- private final TextView mFootlineText;
- private final Button mFootlineAction;
private final View mSettingsButton;
- private final View mFooter;
private final List<VolumeRow> mRows = new ArrayList<VolumeRow>();
private final SpTexts mSpTexts;
private final SparseBooleanArray mDynamic = new SparseBooleanArray();
private final KeyguardManager mKeyguard;
private final int mExpandButtonAnimationDuration;
- private final View mTextFooter;
private final ZenFooter mZenFooter;
private final LayoutTransition mLayoutTransition;
private final Object mSafetyWarningLock = new Object();
@@ -108,8 +102,6 @@ public class VolumeDialog {
private boolean mExpanded;
private int mActiveStream;
private boolean mShowHeaders = VolumePrefs.DEFAULT_SHOW_HEADERS;
- private boolean mShowFooter = VolumePrefs.DEFAULT_SHOW_FOOTER;
- private boolean mShowZenFooter = VolumePrefs.DEFAULT_ZEN_FOOTER;
private boolean mAutomute = VolumePrefs.DEFAULT_ENABLE_AUTOMUTE;
private boolean mSilentMode = VolumePrefs.DEFAULT_ENABLE_SILENT_MODE;
private State mState;
@@ -118,7 +110,7 @@ public class VolumeDialog {
private SafetyWarningDialog mSafetyWarning;
private Callback mCallback;
- public VolumeDialog(Context context, VolumeDialogController controller,
+ public VolumeDialog(Context context, int windowType, VolumeDialogController controller,
ZenModeController zenModeController, Callback callback) {
mContext = context;
mController = controller;
@@ -141,7 +133,7 @@ public class VolumeDialog {
mDialog.setCanceledOnTouchOutside(true);
final Resources res = mContext.getResources();
final WindowManager.LayoutParams lp = window.getAttributes();
- lp.type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+ lp.type = windowType;
lp.format = PixelFormat.TRANSLUCENT;
lp.setTitle(VolumeDialog.class.getSimpleName());
lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
@@ -176,17 +168,11 @@ public class VolumeDialog {
addRow(AudioManager.STREAM_SYSTEM,
R.drawable.ic_volume_system, R.drawable.ic_volume_system_mute, false);
- mTextFooter = mDialog.findViewById(R.id.volume_text_footer);
- mFootlineText = (TextView) mDialog.findViewById(R.id.volume_footline_text);
- mSpTexts.add(mFootlineText);
- mFootlineAction = (Button) mDialog.findViewById(R.id.volume_footline_action_button);
- mSpTexts.add(mFootlineAction);
- mFooter = mDialog.findViewById(R.id.volume_footer);
mSettingsButton = mDialog.findViewById(R.id.volume_settings_button);
mSettingsButton.setOnClickListener(mClickSettings);
mExpandButtonAnimationDuration = res.getInteger(R.integer.volume_expand_animation_duration);
mZenFooter = (ZenFooter) mDialog.findViewById(R.id.volume_zen_footer);
- mZenFooter.init(zenModeController, mZenFooterCallback);
+ mZenFooter.init(zenModeController);
controller.addCallback(mControllerCallbackH, mHandler);
controller.getState();
@@ -217,18 +203,6 @@ public class VolumeDialog {
mHandler.sendEmptyMessage(H.RECHECK_ALL);
}
- public void setShowFooter(boolean show) {
- if (mShowFooter == show) return;
- mShowFooter = show;
- mHandler.sendEmptyMessage(H.RECHECK_ALL);
- }
-
- public void setZenFooter(boolean zen) {
- if (mShowZenFooter == zen) return;
- mShowZenFooter = zen;
- mHandler.sendEmptyMessage(H.RECHECK_ALL);
- }
-
public void setAutomute(boolean automute) {
if (mAutomute == automute) return;
mAutomute = automute;
@@ -315,7 +289,6 @@ public class VolumeDialog {
writer.print(" mActiveStream: "); writer.println(mActiveStream);
writer.print(" mDynamic: "); writer.println(mDynamic);
writer.print(" mShowHeaders: "); writer.println(mShowHeaders);
- writer.print(" mShowFooter: "); writer.println(mShowFooter);
writer.print(" mAutomute: "); writer.println(mAutomute);
writer.print(" mSilentMode: "); writer.println(mSilentMode);
}
@@ -444,7 +417,6 @@ public class VolumeDialog {
}
private int computeTimeoutH() {
- if (mZenFooter != null && mZenFooter.isFooterExpanded()) return 10000;
if (mSafetyWarning != null) return 5000;
if (mExpanded || mExpanding) return 5000;
if (mActiveStream == AudioManager.STREAM_MUSIC) return 1500;
@@ -515,18 +487,9 @@ public class VolumeDialog {
final VolumeRow activeRow = getActiveRow();
updateFooterH();
updateExpandButtonH();
- final boolean footerVisible = mFooter.getVisibility() == View.VISIBLE;
if (!mShowing) {
trimObsoleteH();
}
- // first, find the last visible row
- VolumeRow lastVisible = null;
- for (VolumeRow row : mRows) {
- final boolean isActive = row == activeRow;
- if (isVisibleH(row, isActive)) {
- lastVisible = row;
- }
- }
// apply changes to all rows
for (VolumeRow row : mRows) {
final boolean isActive = row == activeRow;
@@ -542,8 +505,7 @@ public class VolumeDialog {
row.settingsButton.setImageResource(expandButtonRes);
}
}
- Util.setVisOrInvis(row.settingsButton,
- mExpanded && (!footerVisible && row == lastVisible));
+ Util.setVisOrInvis(row.settingsButton, false);
row.header.setAlpha(mExpanded && isActive ? 1 : 0.5f);
}
}
@@ -585,51 +547,9 @@ public class VolumeDialog {
updateFooterH();
}
- private void updateTextFooterH() {
- final boolean zen = mState.zenMode != Global.ZEN_MODE_OFF;
- final boolean wasVisible = mFooter.getVisibility() == View.VISIBLE;
- Util.setVisOrGone(mTextFooter, mExpanded && mShowFooter && (zen || mShowing && wasVisible));
- if (mTextFooter.getVisibility() == View.VISIBLE) {
- String text = null;
- String action = null;
- if (mState.exitCondition != null) {
- final long countdown = ZenModeConfig.tryParseCountdownConditionId(mState
- .exitCondition.id);
- if (countdown != 0) {
- text = mContext.getString(R.string.volume_dnd_ends_at,
- Util.getShortTime(countdown));
- action = mContext.getString(R.string.volume_end_now);
- }
- }
- if (text == null) {
- text = mContext.getString(R.string.volume_dnd_is_on);
- }
- if (action == null) {
- action = mContext.getString(R.string.volume_turn_off);
- }
- Util.setText(mFootlineText, text);
- Util.setText(mFootlineAction, action);
- mFootlineAction.setOnClickListener(mTurnOffDnd);
- }
- Util.setVisOrGone(mFootlineText, zen);
- Util.setVisOrGone(mFootlineAction, zen);
- }
-
private void updateFooterH() {
- if (!mShowFooter) {
- Util.setVisOrGone(mFooter, false);
- return;
- }
- if (mShowZenFooter) {
- Util.setVisOrGone(mTextFooter, false);
- final boolean ringActive = mActiveStream == AudioManager.STREAM_RING;
- Util.setVisOrGone(mZenFooter, mZenFooter.isZen() && ringActive
- || mShowing && (mExpanded || mZenFooter.getVisibility() == View.VISIBLE));
- mZenFooter.update();
- } else {
- Util.setVisOrGone(mZenFooter, false);
- updateTextFooterH();
- }
+ Util.setVisOrGone(mZenFooter, mState.zenMode != Global.ZEN_MODE_OFF);
+ mZenFooter.update();
}
private void updateVolumeRowH(VolumeRow row) {
@@ -642,12 +562,20 @@ public class VolumeDialog {
}
final boolean isRingStream = row.stream == AudioManager.STREAM_RING;
final boolean isSystemStream = row.stream == AudioManager.STREAM_SYSTEM;
+ final boolean isAlarmStream = row.stream == AudioManager.STREAM_ALARM;
+ final boolean isMusicStream = row.stream == AudioManager.STREAM_MUSIC;
final boolean isRingVibrate = isRingStream
&& mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE;
- final boolean isNoned = (isRingStream || isSystemStream)
- && mState.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
- final boolean isLimited = isRingStream
- && mState.zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ final boolean isRingSilent = isRingStream
+ && mState.ringerModeInternal == AudioManager.RINGER_MODE_SILENT;
+ final boolean isZenAlarms = mState.zenMode == Global.ZEN_MODE_ALARMS;
+ final boolean isZenNone = mState.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
+ final boolean isZenPriority = mState.zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ final boolean isRingZenNone = (isRingStream || isSystemStream) && isZenNone;
+ final boolean isRingLimited = isRingStream && isZenPriority;
+ final boolean zenMuted = isZenAlarms ? (isRingStream || isSystemStream)
+ : isZenNone ? (isRingStream || isSystemStream || isAlarmStream || isMusicStream)
+ : false;
// update slider max
final int max = ss.levelMax * 100;
@@ -663,15 +591,15 @@ public class VolumeDialog {
// update header text
final String text;
- if (isNoned) {
+ if (isRingZenNone) {
text = mContext.getString(R.string.volume_stream_muted_dnd, ss.name);
- } else if (isRingVibrate && isLimited) {
+ } else if (isRingVibrate && isRingLimited) {
text = mContext.getString(R.string.volume_stream_vibrate_dnd, ss.name);
} else if (isRingVibrate) {
text = mContext.getString(R.string.volume_stream_vibrate, ss.name);
} else if (ss.muted || mAutomute && ss.level == 0) {
text = mContext.getString(R.string.volume_stream_muted, ss.name);
- } else if (isLimited) {
+ } else if (isRingLimited) {
text = mContext.getString(R.string.volume_stream_limited_dnd, ss.name);
} else {
text = ss.name;
@@ -679,11 +607,12 @@ public class VolumeDialog {
Util.setText(row.header, text);
// update icon
- final boolean iconEnabled = mAutomute || ss.muteSupported;
+ final boolean iconEnabled = (mAutomute || ss.muteSupported) && !zenMuted;
row.icon.setEnabled(iconEnabled);
row.icon.setAlpha(iconEnabled ? 1 : 0.5f);
final int iconRes =
isRingVibrate ? R.drawable.ic_volume_ringer_vibrate
+ : isRingSilent || zenMuted ? row.cachedIconRes
: ss.routedToBluetooth ?
(ss.muted ? R.drawable.ic_volume_media_bt_mute
: R.drawable.ic_volume_media_bt)
@@ -705,10 +634,11 @@ public class VolumeDialog {
: Events.ICON_STATE_UNKNOWN;
// update slider
- updateVolumeRowSliderH(row);
+ updateVolumeRowSliderH(row, zenMuted);
}
- private void updateVolumeRowSliderH(VolumeRow row) {
+ private void updateVolumeRowSliderH(VolumeRow row, boolean zenMuted) {
+ row.slider.setEnabled(!zenMuted);
if (row.tracking) {
return; // don't update if user is sliding
}
@@ -887,46 +817,6 @@ public class VolumeDialog {
}
};
- private final View.OnClickListener mTurnOffDnd = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mSettingsButton.postDelayed(new Runnable() {
- @Override
- public void run() {
- mController.setZenMode(Global.ZEN_MODE_OFF);
- }
- }, WAIT_FOR_RIPPLE);
- }
- };
-
- private final ZenFooter.Callback mZenFooterCallback = new ZenFooter.Callback() {
- @Override
- public void onFooterExpanded() {
- mHandler.sendEmptyMessage(H.RESCHEDULE_TIMEOUT);
- }
-
- @Override
- public void onSettingsClicked() {
- dismiss(Events.DISMISS_REASON_SETTINGS_CLICKED);
- if (mCallback != null) {
- mCallback.onZenSettingsClicked();
- }
- }
-
- @Override
- public void onDoneClicked() {
- dismiss(Events.DISMISS_REASON_DONE_CLICKED);
- }
-
- @Override
- public void onPrioritySettingsClicked() {
- dismiss(Events.DISMISS_REASON_SETTINGS_CLICKED);
- if (mCallback != null) {
- mCallback.onZenPrioritySettingsClicked();
- }
- }
- };
-
private final class H extends Handler {
private static final int SHOW = 1;
private static final int DISMISS = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 86abfcc..1083f40 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -24,6 +24,7 @@ import android.media.VolumePolicy;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
+import android.view.WindowManager;
import com.android.systemui.SystemUI;
import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -61,7 +62,8 @@ public class VolumeDialogComponent implements VolumeComponent {
}
};
mZenModeController = zen;
- mDialog = new VolumeDialog(context, mController, zen, mVolumeDialogCallback);
+ mDialog = new VolumeDialog(context, WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY,
+ mController, zen, mVolumeDialogCallback);
applyConfiguration();
}
@@ -76,12 +78,10 @@ public class VolumeDialogComponent implements VolumeComponent {
mDialog.setStreamImportant(AudioManager.STREAM_ALARM, true);
mDialog.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
mDialog.setShowHeaders(false);
- mDialog.setShowFooter(true);
- mDialog.setZenFooter(true);
mDialog.setAutomute(true);
mDialog.setSilentMode(false);
mController.setVolumePolicy(mVolumePolicy);
- mController.showDndTile(false);
+ mController.showDndTile(true);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
index 012eb41..3a8081f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
@@ -100,7 +100,7 @@ public class VolumeDialogController {
private boolean mEnabled;
private boolean mDestroyed;
private VolumePolicy mVolumePolicy;
- private boolean mShowDndTile = false;
+ private boolean mShowDndTile = true;
public VolumeDialogController(Context context, ComponentName component) {
mContext = context.getApplicationContext();
@@ -125,6 +125,10 @@ public class VolumeDialogController {
return mAudio;
}
+ public ZenModeConfig getZenModeConfig() {
+ return mNoMan.getZenModeConfig();
+ }
+
public void dismiss() {
mCallbacks.onDismissRequested(Events.DISMISS_REASON_VOLUME_CONTROLLER);
}
@@ -342,7 +346,7 @@ public class VolumeDialogController {
updateRingerModeExternalW(mAudio.getRingerMode());
updateZenModeW();
updateEffectsSuppressorW(mNoMan.getEffectsSuppressor());
- updateExitConditionW();
+ updateZenModeConfigW();
mCallbacks.onStateChanged(mState);
}
@@ -395,17 +399,10 @@ public class VolumeDialogController {
return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION;
}
- private Condition getExitCondition() {
- final ZenModeConfig config = mNoMan.getZenModeConfig();
- return config == null ? null
- : config.manualRule == null ? null
- : config.manualRule.condition;
- }
-
- private boolean updateExitConditionW() {
- final Condition exitCondition = getExitCondition();
- if (Objects.equals(mState.exitCondition, exitCondition)) return false;
- mState.exitCondition = exitCondition;
+ private boolean updateZenModeConfigW() {
+ final ZenModeConfig zenModeConfig = getZenModeConfig();
+ if (Objects.equals(mState.zenModeConfig, zenModeConfig)) return false;
+ mState.zenModeConfig = zenModeConfig;
return true;
}
@@ -750,7 +747,7 @@ public class VolumeDialogController {
changed = updateZenModeW();
}
if (ZEN_MODE_CONFIG_URI.equals(uri)) {
- changed = updateExitConditionW();
+ changed = updateZenModeConfigW();
}
if (changed) {
mCallbacks.onStateChanged(mState);
@@ -943,7 +940,7 @@ public class VolumeDialogController {
public int zenMode;
public ComponentName effectsSuppressor;
public String effectsSuppressorName;
- public Condition exitCondition;
+ public ZenModeConfig zenModeConfig;
public int activeStream = NO_ACTIVE_STREAM;
public State copy() {
@@ -956,7 +953,7 @@ public class VolumeDialogController {
rt.zenMode = zenMode;
if (effectsSuppressor != null) rt.effectsSuppressor = effectsSuppressor.clone();
rt.effectsSuppressorName = effectsSuppressorName;
- if (exitCondition != null) rt.exitCondition = exitCondition.copy();
+ if (zenModeConfig != null) rt.zenModeConfig = zenModeConfig.copy();
rt.activeStream = activeStream;
return rt;
}
@@ -977,10 +974,15 @@ public class VolumeDialogController {
sb.append(",zenMode:").append(zenMode);
sb.append(",effectsSuppressor:").append(effectsSuppressor);
sb.append(",effectsSuppressorName:").append(effectsSuppressorName);
- sb.append(",exitCondition:").append(exitCondition);
+ sb.append(",zenModeConfig:").append(zenModeConfig);
sb.append(",activeStream:").append(activeStream);
return sb.append('}').toString();
}
+
+ public Condition getManualExitCondition() {
+ return zenModeConfig != null && zenModeConfig.manualRule != null
+ ? zenModeConfig.manualRule.condition : null;
+ }
}
public interface Callbacks {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java
index 915e998..04339eb 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java
@@ -32,8 +32,6 @@ public class VolumePrefs {
public static final String PREF_SHOW_HEADERS = "pref_show_headers";
public static final String PREF_SHOW_FAKE_REMOTE_1 = "pref_show_fake_remote_1";
public static final String PREF_SHOW_FAKE_REMOTE_2 = "pref_show_fake_remote_2";
- public static final String PREF_SHOW_FOOTER = "pref_show_footer";
- public static final String PREF_ZEN_FOOTER = "pref_zen_footer";
public static final String PREF_ENABLE_AUTOMUTE = "pref_enable_automute";
public static final String PREF_ENABLE_SILENT_MODE = "pref_enable_silent_mode";
public static final String PREF_DEBUG_LOGGING = "pref_debug_logging";
@@ -46,10 +44,8 @@ public class VolumePrefs {
public static final String PREF_ADJUST_NOTIFICATION = "pref_adjust_notification";
public static final boolean DEFAULT_SHOW_HEADERS = true;
- public static final boolean DEFAULT_SHOW_FOOTER = true;
public static final boolean DEFAULT_ENABLE_AUTOMUTE = true;
public static final boolean DEFAULT_ENABLE_SILENT_MODE = true;
- public static final boolean DEFAULT_ZEN_FOOTER = true;
public static void unregisterCallbacks(Context c, OnSharedPreferenceChangeListener listener) {
prefs(c).unregisterOnSharedPreferenceChangeListener(listener);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index 5f04aaf..2688813 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -103,7 +103,7 @@ public class VolumeUI extends SystemUI {
private void setDefaultVolumeController(boolean register) {
if (register) {
- DndTile.setVisible(mContext, false);
+ DndTile.setVisible(mContext, true);
if (LOGD) Log.d(TAG, "Registering default volume controller");
getVolumeComponent().register();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 775c87d..8aded45 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -16,20 +16,12 @@
package com.android.systemui.volume;
import android.animation.LayoutTransition;
-import android.animation.ValueAnimator;
-import android.app.ActivityManager;
import android.content.Context;
-import android.content.res.Resources;
import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
import android.view.View;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
-import android.widget.Switch;
import android.widget.TextView;
import com.android.systemui.R;
@@ -38,70 +30,36 @@ import com.android.systemui.statusbar.policy.ZenModeController;
import java.util.Objects;
/**
- * Switch bar + zen mode panel (conditions) attached to the bottom of the volume dialog.
+ * Zen mode information (and end button) attached to the bottom of the volume dialog.
*/
public class ZenFooter extends LinearLayout {
private static final String TAG = Util.logTag(ZenFooter.class);
private final Context mContext;
- private final float mSecondaryAlpha;
- private final LayoutTransition mLayoutTransition;
- private ZenModeController mController;
- private Switch mSwitch;
- private ZenModePanel mZenModePanel;
- private View mZenModePanelButtons;
- private View mZenModePanelMoreButton;
- private View mZenModePanelDoneButton;
- private View mSwitchBar;
- private View mSwitchBarIcon;
- private View mSummary;
private TextView mSummaryLine1;
private TextView mSummaryLine2;
- private boolean mFooterExpanded;
+ private View mEndNowButton;
private int mZen = -1;
private ZenModeConfig mConfig;
- private Callback mCallback;
+ private ZenModeController mController;
public ZenFooter(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
- mSecondaryAlpha = getFloat(context.getResources(), R.dimen.volume_secondary_alpha);
- mLayoutTransition = new LayoutTransition();
- mLayoutTransition.setDuration(new ValueAnimator().getDuration() / 2);
- mLayoutTransition.disableTransitionType(LayoutTransition.DISAPPEARING);
- mLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
- }
-
- private static float getFloat(Resources r, int resId) {
- final TypedValue tv = new TypedValue();
- r.getValue(resId, tv, true);
- return tv.getFloat();
+ setLayoutTransition(new LayoutTransition());
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mSwitchBar = findViewById(R.id.volume_zen_switch_bar);
- mSwitchBarIcon = findViewById(R.id.volume_zen_switch_bar_icon);
- mSwitch = (Switch) findViewById(R.id.volume_zen_switch);
- mZenModePanel = (ZenModePanel) findViewById(R.id.zen_mode_panel);
- mZenModePanelButtons = findViewById(R.id.volume_zen_mode_panel_buttons);
- mZenModePanelMoreButton = findViewById(R.id.volume_zen_mode_panel_more);
- mZenModePanelDoneButton = findViewById(R.id.volume_zen_mode_panel_done);
- mSummary = findViewById(R.id.volume_zen_panel_summary);
- mSummaryLine1 = (TextView) findViewById(R.id.volume_zen_panel_summary_line_1);
- mSummaryLine2 = (TextView) findViewById(R.id.volume_zen_panel_summary_line_2);
+ mSummaryLine1 = (TextView) findViewById(R.id.volume_zen_summary_line_1);
+ mSummaryLine2 = (TextView) findViewById(R.id.volume_zen_summary_line_2);
+ mEndNowButton = findViewById(R.id.volume_zen_end_now);
}
- public void init(ZenModeController controller, Callback callback) {
- mCallback = callback;
- mController = controller;
- mZenModePanel.init(controller);
- mZenModePanel.setEmbedded(true);
- mZenModePanel.setCallback(mZenModePanelCallback);
- mSwitch.setOnCheckedChangeListener(mCheckedListener);
- mController.addCallback(new ZenModeController.Callback() {
+ public void init(final ZenModeController controller) {
+ controller.addCallback(new ZenModeController.Callback() {
@Override
public void onZenChanged(int zen) {
setZen(zen);
@@ -111,30 +69,15 @@ public class ZenFooter extends LinearLayout {
setConfig(config);
}
});
- mSwitchBar.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mSwitch.setChecked(!mSwitch.isChecked());
- }
- });
- mZenModePanelMoreButton.setOnClickListener(new OnClickListener() {
+ mEndNowButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- if (mCallback != null) {
- mCallback.onSettingsClicked();
- }
+ controller.setZen(Global.ZEN_MODE_OFF, null, TAG);
}
});
- mZenModePanelDoneButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mCallback != null) {
- mCallback.onDoneClicked();
- }
- }
- });
- mZen = mController.getZen();
- mConfig = mController.getConfig();
+ mZen = controller.getZen();
+ mConfig = controller.getConfig();
+ mController = controller;
update();
}
@@ -166,96 +109,17 @@ public class ZenFooter extends LinearLayout {
return mZen == Global.ZEN_MODE_NO_INTERRUPTIONS;
}
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- setLayoutTransition(null);
- setFooterExpanded(false);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- setLayoutTransition(mLayoutTransition);
- }
-
- private boolean setFooterExpanded(boolean expanded) {
- if (mFooterExpanded == expanded) return false;
- mFooterExpanded = expanded;
- update();
- if (mCallback != null) {
- mCallback.onFooterExpanded();
- }
- return true;
- }
-
- public boolean isFooterExpanded() {
- return mFooterExpanded;
- }
-
public void update() {
- final boolean isZen = isZen();
- mSwitch.setOnCheckedChangeListener(null);
- mSwitch.setChecked(isZen);
- mSwitch.setOnCheckedChangeListener(mCheckedListener);
- Util.setVisOrGone(mZenModePanel, isZen && mFooterExpanded);
- Util.setVisOrGone(mZenModePanelButtons, isZen && mFooterExpanded);
- Util.setVisOrGone(mSummary, isZen && !mFooterExpanded);
- mSwitchBarIcon.setAlpha(isZen ? 1 : mSecondaryAlpha);
final String line1 =
isZenPriority() ? mContext.getString(R.string.interruption_level_priority)
: isZenAlarms() ? mContext.getString(R.string.interruption_level_alarms)
: isZenNone() ? mContext.getString(R.string.interruption_level_none)
: null;
Util.setText(mSummaryLine1, line1);
+
final String line2 = ZenModeConfig.getConditionSummary(mContext, mConfig,
- ActivityManager.getCurrentUser());
+ mController.getCurrentUser());
Util.setText(mSummaryLine2, line2);
}
- private final ZenModePanel.Callback mZenModePanelCallback = new ZenModePanel.Callback() {
- @Override
- public void onMoreSettings() {
- if (mCallback != null) {
- mCallback.onSettingsClicked();
- }
- }
-
- @Override
- public void onPrioritySettings() {
- if (mCallback != null) {
- mCallback.onPrioritySettingsClicked();
- }
- }
-
- @Override
- public void onInteraction() {
- // noop
- }
-
- @Override
- public void onExpanded(boolean expanded) {
- // noop
- }
- };
-
- private final OnCheckedChangeListener mCheckedListener = new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (D.BUG) Log.d(TAG, "onCheckedChanged " + isChecked);
- if (isChecked != isZen()) {
- final int newZen = isChecked ? Global.ZEN_MODE_ALARMS : Global.ZEN_MODE_OFF;
- mZen = newZen; // this one's optimistic
- setFooterExpanded(isChecked);
- mController.setZen(newZen, null, TAG);
- }
- }
- };
-
- public interface Callback {
- void onFooterExpanded();
- void onSettingsClicked();
- void onDoneClicked();
- void onPrioritySettingsClicked();
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 1b563dc..9f9c9ac 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -41,8 +41,6 @@ import android.util.MathUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
@@ -85,22 +83,14 @@ public class ZenModePanel extends LinearLayout {
private final H mHandler = new H();
private final ZenPrefs mPrefs;
private final IconPulser mIconPulser;
- private final int mSubheadWarningColor;
- private final int mSubheadColor;
- private final Interpolator mInterpolator;
private final TransitionHelper mTransitionHelper = new TransitionHelper();
private final Uri mForeverId;
private String mTag = TAG + "/" + Integer.toHexString(System.identityHashCode(this));
private SegmentedButtons mZenButtons;
- private ViewGroup mZenButtonsContainer;
- private View mZenSubhead;
- private TextView mZenSubheadCollapsed;
- private TextView mZenSubheadExpanded;
- private View mZenEmbeddedDivider;
- private View mMoreSettings;
private View mZenIntroduction;
+ private TextView mZenIntroductionMessage;
private View mZenIntroductionConfirm;
private View mZenIntroductionCustomize;
private LinearLayout mZenConditions;
@@ -113,7 +103,6 @@ public class ZenModePanel extends LinearLayout {
private int mFirstConditionIndex;
private boolean mRequestingConditions;
private Condition mExitCondition;
- private String mExitConditionText;
private int mBucketIndex = -1;
private boolean mExpanded;
private boolean mHidden;
@@ -123,7 +112,6 @@ public class ZenModePanel extends LinearLayout {
private Condition mSessionExitCondition;
private Condition[] mConditions;
private Condition mTimeCondition;
- private boolean mEmbedded;
public ZenModePanel(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -131,10 +119,6 @@ public class ZenModePanel extends LinearLayout {
mPrefs = new ZenPrefs();
mInflater = LayoutInflater.from(mContext.getApplicationContext());
mIconPulser = new IconPulser(mContext);
- mSubheadWarningColor = context.getColor(R.color.system_warning_color);
- mSubheadColor = context.getColor(R.color.qs_subhead);
- mInterpolator = AnimationUtils.loadInterpolator(mContext,
- com.android.internal.R.interpolator.fast_out_slow_in);
mForeverId = Condition.newId(mContext).appendPath("forever").build();
if (DEBUG) Log.d(mTag, "new ZenModePanel");
}
@@ -149,25 +133,13 @@ public class ZenModePanel extends LinearLayout {
pw.print(" mExpanded="); pw.println(mExpanded);
pw.print(" mSessionZen="); pw.println(mSessionZen);
pw.print(" mAttachedZen="); pw.println(mAttachedZen);
- pw.print(" mEmbedded="); pw.println(mEmbedded);
+ pw.print(" mConfirmedPriorityIntroduction=");
+ pw.println(mPrefs.mConfirmedPriorityIntroduction);
+ pw.print(" mConfirmedSilenceIntroduction=");
+ pw.println(mPrefs.mConfirmedSilenceIntroduction);
mTransitionHelper.dump(fd, pw, args);
}
- public void setEmbedded(boolean embedded) {
- if (mEmbedded == embedded) return;
- mEmbedded = embedded;
- mZenButtonsContainer.setLayoutTransition(mEmbedded ? null : newLayoutTransition(null));
- setLayoutTransition(mEmbedded ? null : newLayoutTransition(null));
- if (mEmbedded) {
- mZenButtonsContainer.setBackground(null);
- } else {
- mZenButtonsContainer.setBackgroundResource(R.drawable.qs_background_secondary);
- }
- mZenButtons.getChildAt(3).setVisibility(mEmbedded ? GONE : VISIBLE);
- mZenEmbeddedDivider.setVisibility(mEmbedded ? VISIBLE : GONE);
- updateWidgets();
- }
-
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -179,37 +151,10 @@ public class ZenModePanel extends LinearLayout {
Global.ZEN_MODE_ALARMS);
mZenButtons.addButton(R.string.interruption_level_priority_twoline,
Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
- mZenButtons.addButton(R.string.interruption_level_all, Global.ZEN_MODE_OFF);
mZenButtons.setCallback(mZenButtonsCallback);
- mZenButtonsContainer = (ViewGroup) findViewById(R.id.zen_buttons_container);
- mZenButtonsContainer.setLayoutTransition(newLayoutTransition(null));
-
- mZenSubhead = findViewById(R.id.zen_subhead);
- mZenEmbeddedDivider = findViewById(R.id.zen_embedded_divider);
-
- mZenSubheadCollapsed = (TextView) findViewById(R.id.zen_subhead_collapsed);
- mZenSubheadCollapsed.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- setExpanded(true);
- }
- });
- Interaction.register(mZenSubheadCollapsed, mInteractionCallback);
-
- mZenSubheadExpanded = (TextView) findViewById(R.id.zen_subhead_expanded);
- Interaction.register(mZenSubheadExpanded, mInteractionCallback);
-
- mMoreSettings = findViewById(R.id.zen_more_settings);
- mMoreSettings.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- fireMoreSettings();
- }
- });
- Interaction.register(mMoreSettings, mInteractionCallback);
-
mZenIntroduction = findViewById(R.id.zen_introduction);
+ mZenIntroductionMessage = (TextView) findViewById(R.id.zen_introduction_message);
mZenIntroductionConfirm = findViewById(R.id.zen_introduction_confirm);
mZenIntroductionConfirm.setOnClickListener(new OnClickListener() {
@Override
@@ -230,25 +175,25 @@ public class ZenModePanel extends LinearLayout {
mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions);
- setLayoutTransition(newLayoutTransition(mTransitionHelper));
}
private void confirmZenIntroduction() {
- if (DEBUG) Log.d(TAG, "confirmZenIntroduction");
- Prefs.putBoolean(mContext, Prefs.Key.DND_CONFIRMED_PRIORITY_INTRODUCTION, true);
+ final String prefKey = prefKeyForConfirmation(getSelectedZen(Global.ZEN_MODE_OFF));
+ if (prefKey == null) return;
+ if (DEBUG) Log.d(TAG, "confirmZenIntroduction " + prefKey);
+ Prefs.putBoolean(mContext, prefKey, true);
mHandler.sendEmptyMessage(H.UPDATE_WIDGETS);
}
- private LayoutTransition newLayoutTransition(TransitionListener listener) {
- final LayoutTransition transition = new LayoutTransition();
- transition.disableTransitionType(LayoutTransition.DISAPPEARING);
- transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
- transition.disableTransitionType(LayoutTransition.APPEARING);
- transition.setInterpolator(LayoutTransition.CHANGE_APPEARING, mInterpolator);
- if (listener != null) {
- transition.addTransitionListener(listener);
+ private static String prefKeyForConfirmation(int zen) {
+ switch (zen) {
+ case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
+ return Prefs.Key.DND_CONFIRMED_PRIORITY_INTRODUCTION;
+ case Global.ZEN_MODE_NO_INTERRUPTIONS:
+ return Prefs.Key.DND_CONFIRMED_SILENCE_INTRODUCTION;
+ default:
+ return null;
}
- return transition;
}
@Override
@@ -260,7 +205,6 @@ public class ZenModePanel extends LinearLayout {
mSessionZen = mAttachedZen;
mTransitionHelper.clear();
setSessionExitCondition(copy(mExitCondition));
- refreshExitConditionText();
updateWidgets();
setRequestingConditions(!mHidden);
}
@@ -274,9 +218,6 @@ public class ZenModePanel extends LinearLayout {
mAttachedZen = -1;
mSessionZen = -1;
setSessionExitCondition(null);
- if (!mEmbedded) {
- setExpanded(false);
- }
setRequestingConditions(false);
mTransitionHelper.clear();
}
@@ -359,7 +300,6 @@ public class ZenModePanel extends LinearLayout {
for (int i = 0; i < mMaxConditions; i++) {
mZenConditions.addView(mInflater.inflate(R.layout.zen_mode_condition, this, false));
}
- refreshExitConditionText();
mSessionZen = getSelectedZen(-1);
handleUpdateManualRule(mController.getManualRule());
if (DEBUG) Log.d(mTag, "init mExitCondition=" + mExitCondition);
@@ -375,7 +315,6 @@ public class ZenModePanel extends LinearLayout {
if (Objects.equals(mExitCondition, exitCondition)) return;
mExitCondition = exitCondition;
if (DEBUG) Log.d(mTag, "mExitCondition=" + getConditionId(mExitCondition));
- refreshExitConditionText();
updateWidgets();
}
@@ -395,10 +334,6 @@ public class ZenModePanel extends LinearLayout {
return condition == null ? null : condition.copy();
}
- private void refreshExitConditionText() {
- mExitConditionText = getExitConditionText(mContext, mExitCondition);
- }
-
public static String getExitConditionText(Context context, Condition exitCondition) {
if (exitCondition == null) {
return foreverSummary(context);
@@ -430,7 +365,7 @@ public class ZenModePanel extends LinearLayout {
private void handleUpdateZen(int zen) {
if (mSessionZen != -1 && mSessionZen != zen) {
- setExpanded(mEmbedded && isShown() || !mEmbedded && zen != Global.ZEN_MODE_OFF);
+ setExpanded(isShown());
mSessionZen = zen;
}
mZenButtons.setSelectedValue(zen);
@@ -480,30 +415,18 @@ public class ZenModePanel extends LinearLayout {
return;
}
final int zen = getSelectedZen(Global.ZEN_MODE_OFF);
- final boolean zenOff = zen == Global.ZEN_MODE_OFF;
final boolean zenImportant = zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
- final boolean expanded = !mHidden && mExpanded;
- final boolean conditions = mEmbedded || !zenOff && expanded;
- final boolean introduction = conditions && zenImportant && !mPrefs.mConfirmedIntroduction;
+ final boolean introduction = (zenImportant && !mPrefs.mConfirmedPriorityIntroduction
+ || zenNone && !mPrefs.mConfirmedSilenceIntroduction);
mZenButtons.setVisibility(mHidden ? GONE : VISIBLE);
- mZenSubhead.setVisibility(!mHidden && !zenOff && !mEmbedded ? VISIBLE : GONE);
- mZenSubheadExpanded.setVisibility(expanded ? VISIBLE : GONE);
- mZenSubheadCollapsed.setVisibility(!expanded ? VISIBLE : GONE);
- mMoreSettings.setVisibility(zenImportant && expanded ? VISIBLE : GONE);
- mZenConditions.setVisibility(conditions ? VISIBLE : GONE);
-
- if (zenNone) {
- mZenSubheadExpanded.setText(R.string.zen_no_interruptions_with_warning);
- mZenSubheadCollapsed.setText(mExitConditionText);
- } else if (zenImportant) {
- mZenSubheadExpanded.setText(R.string.zen_important_interruptions);
- mZenSubheadCollapsed.setText(mExitConditionText);
- }
- mZenSubheadExpanded.setTextColor(zenNone && mPrefs.isNoneDangerous()
- ? mSubheadWarningColor : mSubheadColor);
mZenIntroduction.setVisibility(introduction ? VISIBLE : GONE);
+ if (introduction) {
+ mZenIntroductionMessage.setText(zenImportant ? R.string.zen_priority_introduction
+ : R.string.zen_silence_introduction);
+ mZenIntroductionCustomize.setVisibility(zenImportant ? VISIBLE : GONE);
+ }
}
private static Condition parseExistingTimeCondition(Context context, Condition condition) {
@@ -761,13 +684,13 @@ public class ZenModePanel extends LinearLayout {
String modeText;
switch(zen) {
case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
- modeText = mContext.getString(R.string.zen_important_interruptions);
+ modeText = mContext.getString(R.string.interruption_level_priority);
break;
case Global.ZEN_MODE_NO_INTERRUPTIONS:
- modeText = mContext.getString(R.string.zen_no_interruptions);
+ modeText = mContext.getString(R.string.interruption_level_none);
break;
case Global.ZEN_MODE_ALARMS:
- modeText = mContext.getString(R.string.zen_alarms);
+ modeText = mContext.getString(R.string.interruption_level_alarms);
break;
default:
return;
@@ -837,12 +760,6 @@ public class ZenModePanel extends LinearLayout {
setSessionExitCondition(copy(condition));
}
- private void fireMoreSettings() {
- if (mCallback != null) {
- mCallback.onMoreSettings();
- }
- }
-
private void fireInteraction() {
if (mCallback != null) {
mCallback.onInteraction();
@@ -887,7 +804,6 @@ public class ZenModePanel extends LinearLayout {
}
public interface Callback {
- void onMoreSettings();
void onPrioritySettings();
void onInteraction();
void onExpanded(boolean expanded);
@@ -907,7 +823,8 @@ public class ZenModePanel extends LinearLayout {
private int mMinuteIndex;
private int mNoneSelected;
- private boolean mConfirmedIntroduction;
+ private boolean mConfirmedPriorityIntroduction;
+ private boolean mConfirmedSilenceIntroduction;
private ZenPrefs() {
mNoneDangerousThreshold = mContext.getResources()
@@ -915,11 +832,8 @@ public class ZenModePanel extends LinearLayout {
Prefs.registerListener(mContext, this);
updateMinuteIndex();
updateNoneSelected();
- updateConfirmedIntroduction();
- }
-
- public boolean isNoneDangerous() {
- return mNoneSelected < mNoneDangerousThreshold;
+ updateConfirmedPriorityIntroduction();
+ updateConfirmedSilenceIntroduction();
}
public void trackNoneSelected() {
@@ -945,7 +859,8 @@ public class ZenModePanel extends LinearLayout {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
updateMinuteIndex();
updateNoneSelected();
- updateConfirmedIntroduction();
+ updateConfirmedPriorityIntroduction();
+ updateConfirmedSilenceIntroduction();
}
private void updateMinuteIndex() {
@@ -968,12 +883,22 @@ public class ZenModePanel extends LinearLayout {
return MathUtils.constrain(noneSelected, 0, Integer.MAX_VALUE);
}
- private void updateConfirmedIntroduction() {
+ private void updateConfirmedPriorityIntroduction() {
final boolean confirmed = Prefs.getBoolean(mContext,
Prefs.Key.DND_CONFIRMED_PRIORITY_INTRODUCTION, false);
- if (confirmed == mConfirmedIntroduction) return;
- mConfirmedIntroduction = confirmed;
- if (DEBUG) Log.d(mTag, "Confirmed introduction: " + mConfirmedIntroduction);
+ if (confirmed == mConfirmedPriorityIntroduction) return;
+ mConfirmedPriorityIntroduction = confirmed;
+ if (DEBUG) Log.d(mTag, "Confirmed priority introduction: "
+ + mConfirmedPriorityIntroduction);
+ }
+
+ private void updateConfirmedSilenceIntroduction() {
+ final boolean confirmed = Prefs.getBoolean(mContext,
+ Prefs.Key.DND_CONFIRMED_SILENCE_INTRODUCTION, false);
+ if (confirmed == mConfirmedSilenceIntroduction) return;
+ mConfirmedSilenceIntroduction = confirmed;
+ if (DEBUG) Log.d(mTag, "Confirmed silence introduction: "
+ + mConfirmedSilenceIntroduction);
}
}
@@ -981,12 +906,16 @@ public class ZenModePanel extends LinearLayout {
@Override
public void onSelected(final Object value) {
if (value != null && mZenButtons.isShown() && isAttachedToWindow()) {
- if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + value);
+ final int zen = (Integer) value;
+ if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + zen);
final Uri realConditionId = getRealConditionId(mSessionExitCondition);
AsyncTask.execute(new Runnable() {
@Override
public void run() {
- mController.setZen((Integer) value, realConditionId, TAG + ".selectZen");
+ mController.setZen(zen, realConditionId, TAG + ".selectZen");
+ if (zen != Global.ZEN_MODE_OFF) {
+ Prefs.putInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, zen);
+ }
}
});
}