Merge "New behavior for docked stack when going home" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index 2b1c42e..3240467 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4880,7 +4880,6 @@
method public android.graphics.drawable.Icon getLargeIcon();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
- method public android.app.Notification.Topic getTopic();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -4944,7 +4943,6 @@
field public static final int PRIORITY_MAX = 2; // 0x2
field public static final int PRIORITY_MIN = -2; // 0xfffffffe
field public static final deprecated int STREAM_DEFAULT = -1; // 0xffffffff
- field public static final java.lang.String TOPIC_DEFAULT = "system_default_topic";
field public static final int VISIBILITY_PRIVATE = 0; // 0x0
field public static final int VISIBILITY_PUBLIC = 1; // 0x1
field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
@@ -5096,7 +5094,6 @@
method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
- method public android.app.Notification.Builder setTopic(android.app.Notification.Topic);
method public android.app.Notification.Builder setUsesChronometer(boolean);
method public android.app.Notification.Builder setVibrate(long[]);
method public android.app.Notification.Builder setVisibility(int);
@@ -5164,16 +5161,6 @@
field protected android.app.Notification.Builder mBuilder;
}
- public static class Notification.Topic implements android.os.Parcelable {
- ctor public Notification.Topic(java.lang.String, java.lang.CharSequence);
- method public android.app.Notification.Topic clone();
- method public int describeContents();
- method public java.lang.String getId();
- method public java.lang.CharSequence getLabel();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.app.Notification.Topic> CREATOR;
- }
-
public static final class Notification.WearableExtender implements android.app.Notification.Extender {
ctor public Notification.WearableExtender();
ctor public Notification.WearableExtender(android.app.Notification);
@@ -5236,7 +5223,7 @@
method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
method public java.util.List<android.app.AutomaticZenRule> getAutomaticZenRules();
method public final int getCurrentInterruptionFilter();
- method public int getImportance(java.lang.String);
+ method public int getImportance();
method public android.app.NotificationManager.Policy getNotificationPolicy();
method public boolean isNotificationPolicyAccessGranted();
method public void notify(int, android.app.Notification);
@@ -34592,6 +34579,7 @@
method public final void startActivityAndCollapse(android.content.Intent);
method public final void unlockAndRun(java.lang.Runnable);
field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+ field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
field public static final int TILE_MODE_ACTIVE = 2; // 0x2
field public static final int TILE_MODE_PASSIVE = 1; // 0x1
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 2e9e08f..7dde390 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5012,7 +5012,6 @@
method public android.graphics.drawable.Icon getLargeIcon();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
- method public android.app.Notification.Topic getTopic();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -5076,7 +5075,6 @@
field public static final int PRIORITY_MAX = 2; // 0x2
field public static final int PRIORITY_MIN = -2; // 0xfffffffe
field public static final deprecated int STREAM_DEFAULT = -1; // 0xffffffff
- field public static final java.lang.String TOPIC_DEFAULT = "system_default_topic";
field public static final int VISIBILITY_PRIVATE = 0; // 0x0
field public static final int VISIBILITY_PUBLIC = 1; // 0x1
field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
@@ -5228,7 +5226,6 @@
method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
- method public android.app.Notification.Builder setTopic(android.app.Notification.Topic);
method public android.app.Notification.Builder setUsesChronometer(boolean);
method public android.app.Notification.Builder setVibrate(long[]);
method public android.app.Notification.Builder setVisibility(int);
@@ -5296,16 +5293,6 @@
field protected android.app.Notification.Builder mBuilder;
}
- public static class Notification.Topic implements android.os.Parcelable {
- ctor public Notification.Topic(java.lang.String, java.lang.CharSequence);
- method public android.app.Notification.Topic clone();
- method public int describeContents();
- method public java.lang.String getId();
- method public java.lang.CharSequence getLabel();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.app.Notification.Topic> CREATOR;
- }
-
public static final class Notification.WearableExtender implements android.app.Notification.Extender {
ctor public Notification.WearableExtender();
ctor public Notification.WearableExtender(android.app.Notification);
@@ -5368,7 +5355,7 @@
method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
method public java.util.List<android.app.AutomaticZenRule> getAutomaticZenRules();
method public final int getCurrentInterruptionFilter();
- method public int getImportance(java.lang.String);
+ method public int getImportance();
method public android.app.NotificationManager.Policy getNotificationPolicy();
method public boolean isNotificationPolicyAccessGranted();
method public void notify(int, android.app.Notification);
@@ -36984,9 +36971,8 @@
field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb
field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
- field public static final int REASON_PACKAGE_SUSPENDED = 15; // 0xf
- field public static final int REASON_PROFILE_TURNED_OFF = 16; // 0x10
- field public static final int REASON_TOPIC_BANNED = 14; // 0xe
+ field public static final int REASON_PACKAGE_SUSPENDED = 14; // 0xe
+ field public static final int REASON_PROFILE_TURNED_OFF = 15; // 0xf
field public static final int REASON_USER_STOPPED = 6; // 0x6
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
}
@@ -37148,6 +37134,7 @@
method public final void startActivityAndCollapse(android.content.Intent);
method public final void unlockAndRun(java.lang.Runnable);
field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+ field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
field public static final int TILE_MODE_ACTIVE = 2; // 0x2
field public static final int TILE_MODE_PASSIVE = 1; // 0x1
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 550d6df..287f785 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4880,7 +4880,6 @@
method public android.graphics.drawable.Icon getLargeIcon();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
- method public android.app.Notification.Topic getTopic();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -4944,7 +4943,6 @@
field public static final int PRIORITY_MAX = 2; // 0x2
field public static final int PRIORITY_MIN = -2; // 0xfffffffe
field public static final deprecated int STREAM_DEFAULT = -1; // 0xffffffff
- field public static final java.lang.String TOPIC_DEFAULT = "system_default_topic";
field public static final int VISIBILITY_PRIVATE = 0; // 0x0
field public static final int VISIBILITY_PUBLIC = 1; // 0x1
field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
@@ -5096,7 +5094,6 @@
method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
- method public android.app.Notification.Builder setTopic(android.app.Notification.Topic);
method public android.app.Notification.Builder setUsesChronometer(boolean);
method public android.app.Notification.Builder setVibrate(long[]);
method public android.app.Notification.Builder setVisibility(int);
@@ -5164,16 +5161,6 @@
field protected android.app.Notification.Builder mBuilder;
}
- public static class Notification.Topic implements android.os.Parcelable {
- ctor public Notification.Topic(java.lang.String, java.lang.CharSequence);
- method public android.app.Notification.Topic clone();
- method public int describeContents();
- method public java.lang.String getId();
- method public java.lang.CharSequence getLabel();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.app.Notification.Topic> CREATOR;
- }
-
public static final class Notification.WearableExtender implements android.app.Notification.Extender {
ctor public Notification.WearableExtender();
ctor public Notification.WearableExtender(android.app.Notification);
@@ -5236,7 +5223,7 @@
method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
method public java.util.List<android.app.AutomaticZenRule> getAutomaticZenRules();
method public final int getCurrentInterruptionFilter();
- method public int getImportance(java.lang.String);
+ method public int getImportance();
method public android.app.NotificationManager.Policy getNotificationPolicy();
method public boolean isNotificationPolicyAccessGranted();
method public void notify(int, android.app.Notification);
@@ -34607,6 +34594,7 @@
method public final void startActivityAndCollapse(android.content.Intent);
method public final void unlockAndRun(java.lang.Runnable);
field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+ field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
field public static final int TILE_MODE_ACTIVE = 2; // 0x2
field public static final int TILE_MODE_PASSIVE = 1; // 0x1
}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 3c8dfce..8be00aa 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -48,16 +48,13 @@
boolean areNotificationsEnabledForPackage(String pkg, int uid);
boolean areNotificationsEnabled(String pkg);
- ParceledListSlice getTopics(String pkg, int uid);
- void setVisibilityOverride(String pkg, int uid, in Notification.Topic topic, int visibility);
- int getVisibilityOverride(String pkg, int uid, in Notification.Topic topic);
- void setPriority(String pkg, int uid, in Notification.Topic topic, int priority);
- int getPriority(String pkg, int uid, in Notification.Topic topic);
- void setImportance(String pkg, int uid, in Notification.Topic topic, int importance);
- int getImportance(String pkg, int uid, in Notification.Topic topic);
- int getTopicImportance(String pkg, String topicId);
- boolean doesUserUseTopics(String pkg, int uid);
- boolean hasBannedTopics(String pkg, int uid);
+ void setVisibilityOverride(String pkg, int uid, int visibility);
+ int getVisibilityOverride(String pkg, int uid);
+ void setPriority(String pkg, int uid, int priority);
+ int getPriority(String pkg, int uid);
+ void setImportance(String pkg, int uid, int importance);
+ int getImportance(String pkg, int uid);
+ int getPackageImportance(String pkg);
// TODO: Remove this when callers have been migrated to the equivalent
// INotificationListener method.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 52631d1..13b5b5c8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1366,98 +1366,6 @@
public Notification publicVersion;
/**
- * Structure to encapsulate a topic that is shown in Notification settings.
- * It must include an id and label.
- */
- public static class Topic implements Parcelable {
- private final String id;
- private final CharSequence label;
-
- public Topic(String id, CharSequence label) {
- this.id = id;
- this.label = safeCharSequence(label);
- }
-
- private Topic(Parcel in) {
- if (in.readInt() != 0) {
- id = in.readString();
- } else {
- id = null;
- }
- label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- }
-
- public String getId() {
- return id;
- }
-
- public CharSequence getLabel() {
- return label;
- }
-
- @Override
- public String toString() {
- return new StringBuilder(Topic.class.getSimpleName()).append('[')
- .append("id=").append(id)
- .append(",label=").append(label)
- .append(']').toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof Topic)) return false;
- if (o == this) return true;
- final Topic other = (Topic) o;
- return Objects.equals(other.id, id)
- && Objects.equals(other.label, label);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, label);
- }
-
- @Override
- public Topic clone() {
- return new Topic(id, label);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- if (id != null) {
- out.writeInt(1);
- out.writeString(id);
- } else {
- out.writeInt(0);
- }
- TextUtils.writeToParcel(label, out, flags);
- }
- public static final Parcelable.Creator<Topic> CREATOR =
- new Parcelable.Creator<Topic>() {
- public Topic createFromParcel(Parcel in) {
- return new Topic(in);
- }
- public Topic[] newArray(int size) {
- return new Topic[size];
- }
- };
- }
-
- @SystemApi
- public static final String TOPIC_DEFAULT = "system_default_topic";
-
- private Topic topic;
-
- public Topic getTopic() {
- return topic;
- }
-
- /**
* Constructs a Notification object with default values.
* You might want to consider using {@link Builder} instead.
*/
@@ -1583,10 +1491,6 @@
}
color = parcel.readInt();
-
- if (parcel.readInt() != 0) {
- topic = Topic.CREATOR.createFromParcel(parcel);
- }
}
@Override
@@ -1687,10 +1591,6 @@
that.color = this.color;
- if (this.topic != null) {
- that.topic = this.topic.clone();
- }
-
if (!heavy) {
that.lightenPayload(); // will clean out extras
}
@@ -1871,13 +1771,6 @@
}
parcel.writeInt(color);
-
- if (topic != null) {
- parcel.writeInt(1);
- topic.writeToParcel(parcel, 0);
- } else {
- parcel.writeInt(0);
- }
}
/**
@@ -2020,10 +1913,6 @@
sb.append(" publicVersion=");
sb.append(publicVersion.toString());
}
- if (topic != null) {
- sb.append("topic=");
- sb.append(topic.toString());
- }
sb.append(")");
return sb.toString();
}
@@ -2995,19 +2884,6 @@
return this;
}
- /**
- * Sets the topic of this notification. Topics are typically displayed in Notification
- * settings.
- * <p>
- * Every topic must have an id and a textual label.
- *
- * @param topic The topic to add.
- */
- public Builder setTopic(Topic topic) {
- mN.topic = topic;
- return this;
- }
-
private Drawable getProfileBadgeDrawable() {
// Note: This assumes that the current user can read the profile badge of the
// originating user.
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index ff2cfd6..324a0ab 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -507,11 +507,10 @@
return false;
}
- public int getImportance(String topicId) {
- Preconditions.checkNotNull(topicId);
+ public int getImportance() {
INotificationManager service = getService();
try {
- return service.getTopicImportance(mContext.getPackageName(), topicId);
+ return service.getPackageImportance(mContext.getPackageName());
} catch (RemoteException e) {
}
return NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b33e807..a738b2e 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2827,7 +2827,7 @@
final long wifiOnTime = getWifiOnTime(rawRealtime, which);
final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
dumpLine(pw, 0 /* uid */, category, GLOBAL_WIFI_DATA, wifiOnTime / 1000,
- wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */ 0, 0, 0, 0);
+ wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */ 0, 0, 0);
dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_WIFI_CONTROLLER_DATA,
getWifiControllerActivity(), which);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7ba48b9..512ac92 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -114,6 +114,21 @@
"android.settings.LOCATION_SOURCE_SETTINGS";
/**
+ * Activity Action: Show settings to allow configuration of users.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_USER_SETTINGS =
+ "android.settings.USER_SETTINGS";
+
+ /**
* Activity Action: Show settings to allow configuration of wireless controls
* such as Wi-Fi, Bluetooth and Mobile networks.
* <p>
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index fb58f4e..b5387f1 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -97,14 +97,11 @@
/** Notification was canceled because it was an invisible member of a group. */
public static final int REASON_GROUP_OPTIMIZATION = 13;
- /** Notification was canceled by the user banning the topic. */
- public static final int REASON_TOPIC_BANNED = 14;
-
/** Notification was canceled by the device administrator suspending the package. */
- public static final int REASON_PACKAGE_SUSPENDED = 15;
+ public static final int REASON_PACKAGE_SUSPENDED = 14;
/** Notification was canceled by the owning managed profile being turned off. */
- public static final int REASON_PROFILE_TURNED_OFF = 16;
+ public static final int REASON_PROFILE_TURNED_OFF = 15;
public class Adjustment {
int mImportance;
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 0cf1175..553d539 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -16,6 +16,8 @@
package android.service.quicksettings;
import android.Manifest;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.app.Dialog;
import android.app.Service;
@@ -74,6 +76,14 @@
public class TileService extends Service {
/**
+ * An activity that provides a user interface for adjusting TileService preferences.
+ * Optional but recommended for apps that implement a TileService.
+ */
+ @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+ public static final String ACTION_QS_TILE_PREFERENCES
+ = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
+
+ /**
* Action that identifies a Service as being a TileService.
*/
public static final String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 016ed60..3a185d6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1992,10 +1992,10 @@
See {@link com.android.server.notification.NotificationSignalExtractor} -->
<string-array name="config_notificationSignalExtractors">
<item>com.android.server.notification.ValidateNotificationPeople</item>
- <item>com.android.server.notification.TopicPriorityExtractor</item>
- <item>com.android.server.notification.TopicImportanceExtractor</item>
+ <item>com.android.server.notification.PriorityExtractor</item>
+ <item>com.android.server.notification.ImportanceExtractor</item>
<item>com.android.server.notification.NotificationIntrusivenessExtractor</item>
- <item>com.android.server.notification.TopicVisibilityExtractor</item>
+ <item>com.android.server.notification.VisibilityExtractor</item>
</string-array>
<!-- Flag indicating that this device does not rotate and will always remain in its default
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1f0e96d..da88146 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4162,9 +4162,7 @@
<item quantity="other"><xliff:g id="count" example="3">%1$d</xliff:g> selected</item>
</plurals>
- <string name="default_notification_topic_label">Miscellaneous</string>
-
- <string name="importance_from_topic">You set the importance of these notifications.</string>
+ <string name="importance_from_user">You set the importance of these notifications.</string>
<string name="importance_from_person">This is important because of the people involved.</string>
<!-- Message to user that app trying to create user for an account that already exists. [CHAR LIMIT=none] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fc9f7a4..719e554 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2389,7 +2389,6 @@
<java-symbol type="string" name="config_iccHotswapPromptForRestartDialogComponent" />
<java-symbol type="string" name="config_packagedKeyboardName" />
- <java-symbol type="string" name="default_notification_topic_label" />
<java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" />
<java-symbol type="color" name="system_bar_background_semi_transparent" />
@@ -2428,7 +2427,7 @@
<java-symbol type="dimen" name="notification_content_margin_end" />
<java-symbol type="dimen" name="notification_content_picture_margin" />
<java-symbol type="dimen" name="notification_content_margin_top" />
- <java-symbol type="string" name="importance_from_topic" />
+ <java-symbol type="string" name="importance_from_user" />
<java-symbol type="string" name="importance_from_person" />
<java-symbol type="layout" name="work_widget_mask_view" />
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 6257122..8660b75 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -7,7 +7,7 @@
# Enables fine-grained GLES error checking
# If set to true, every GLES call is wrapped & error checked
# Has moderate overhead
-HWUI_ENABLE_OPENGL_VALIDATION := false
+HWUI_ENABLE_OPENGL_VALIDATION := true
hwui_src_files := \
font/CacheTexture.cpp \
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index fd96391..216509d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -18,6 +18,7 @@
import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.Shared.TAG;
+import static com.android.internal.util.Preconditions.checkState;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
@@ -40,6 +41,7 @@
import com.android.documentsui.model.RootInfo;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
@@ -85,15 +87,13 @@
// Create a new anonymous "Recents" RootInfo. It's a faker.
mRecentsRoot = new RootInfo() {{
- // Special root for recents
- authority = null;
- rootId = null;
- derivedIcon = R.drawable.ic_root_recent;
- derivedType = RootInfo.TYPE_RECENTS;
- flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD;
- title = mContext.getString(R.string.root_recent);
- availableBytes = -1;
- }};
+ // Special root for recents
+ derivedIcon = R.drawable.ic_root_recent;
+ derivedType = RootInfo.TYPE_RECENTS;
+ flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD;
+ title = mContext.getString(R.string.root_recent);
+ availableBytes = -1;
+ }};
}
private class RootsChangedObserver extends ContentObserver {
@@ -116,6 +116,16 @@
* Gather roots from all known storage providers.
*/
public void updateAsync() {
+ // Verifying an assumption about the recents root being immutable.
+ if (DEBUG) {
+ checkState(mRecentsRoot.authority == null);
+ checkState(mRecentsRoot.rootId == null);
+ checkState(mRecentsRoot.derivedIcon == R.drawable.ic_root_recent);
+ checkState(mRecentsRoot.derivedType == RootInfo.TYPE_RECENTS);
+ checkState(mRecentsRoot.flags == (Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD));
+ checkState(mRecentsRoot.title == mContext.getString(R.string.root_recent));
+ checkState(mRecentsRoot.availableBytes == -1);
+ }
new UpdateTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@@ -412,9 +422,10 @@
if (!state.showAdvanced && root.isAdvanced()) continue;
// Exclude non-local devices when local only
if (state.localOnly && !root.isLocalOnly()) continue;
- // Exclude downloads roots that don't support directory creation
- // TODO: Add flag to check the root supports directory creation or not.
- if (state.directoryCopy && !root.supportsChildren()) continue;
+ // Exclude downloads roots as it doesn't support directory creation (actually
+ // we just don't show them).
+ // TODO: Add flag to check the root supports directory creation.
+ if (state.directoryCopy && !root.isDownloads()) continue;
// Only show empty roots when creating, or in browse mode.
if (root.isEmpty() && (state.action == State.ACTION_OPEN
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index f908eeb..9f83c04 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -45,7 +45,6 @@
import android.widget.ListView;
import android.widget.TextView;
-import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;
import java.util.ArrayList;
@@ -403,17 +402,7 @@
public static class RootComparator implements Comparator<RootItem> {
@Override
public int compare(RootItem lhs, RootItem rhs) {
- // Sort by root type, then title, then summary.
- int score = lhs.root.derivedType - rhs.root.derivedType;
- if (score != 0) {
- return score;
- }
- score = DocumentInfo.compareToIgnoreCaseNullable(lhs.root.title, rhs.root.title);
- if (score != 0) {
- return score;
- }
-
- return DocumentInfo.compareToIgnoreCaseNullable(lhs.root.summary, rhs.root.summary);
+ return lhs.root.compareTo(rhs.root);
}
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
index 22cb25a2..b90a119 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -17,14 +17,17 @@
package com.android.documentsui;
import android.content.Context;
+import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Time;
+import java.text.Collator;
import java.util.ArrayList;
import java.util.List;
/** @hide */
public final class Shared {
+
/** Intent action name to pick a copy destination. */
public static final String ACTION_PICK_COPY_DESTINATION =
"com.android.documentsui.PICK_COPY_DESTINATION";
@@ -39,6 +42,19 @@
public static final String TAG = "Documents";
public static final String EXTRA_STACK = "com.android.documentsui.STACK";
+
+ /**
+ * String prefix used to indicate the document is a directory.
+ */
+ public static final char DIR_PREFIX = '\001';
+
+ private static final Collator sCollator;
+
+ static {
+ sCollator = Collator.getInstance();
+ sCollator.setStrength(Collator.SECONDARY);
+ }
+
/**
* Generates a formatted quantity string.
*/
@@ -76,4 +92,26 @@
? (ArrayList<T>) list
: new ArrayList<T>(list);
}
+
+ /**
+ * Compare two strings against each other using system default collator in a
+ * case-insensitive mode. Clusters strings prefixed with {@link DIR_PREFIX}
+ * before other items.
+ */
+ public static int compareToIgnoreCaseNullable(String lhs, String rhs) {
+ final boolean leftEmpty = TextUtils.isEmpty(lhs);
+ final boolean rightEmpty = TextUtils.isEmpty(rhs);
+
+ if (leftEmpty && rightEmpty) return 0;
+ if (leftEmpty) return -1;
+ if (rightEmpty) return 1;
+
+ final boolean leftDir = (lhs.charAt(0) == DIR_PREFIX);
+ final boolean rightDir = (rhs.charAt(0) == DIR_PREFIX);
+
+ if (leftDir && !rightDir) return -1;
+ if (rightDir && !leftDir) return 1;
+
+ return sCollator.compare(lhs, rhs);
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 0a9789f..4583dec 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -1071,8 +1071,8 @@
return false;
}
- // Can't copy folders to roots that don't support children.
- if (!root.supportsChildren()) {
+ // Can't copy folders to downloads, because we don't show folders there.
+ if (!root.isDownloads()) {
for (DocumentInfo docs : files) {
if (docs.isDirectory()) {
return false;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
index b369448..9684a5a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
@@ -35,6 +35,7 @@
import com.android.documentsui.DirectoryResult;
import com.android.documentsui.RootCursorWrapper;
+import com.android.documentsui.Shared;
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
import com.android.documentsui.model.DocumentInfo;
@@ -170,7 +171,7 @@
final String displayName = getCursorString(
mCursor, Document.COLUMN_DISPLAY_NAME);
if (Document.MIME_TYPE_DIR.equals(mimeType)) {
- stringValues[pos] = DocumentInfo.DIR_PREFIX + displayName;
+ stringValues[pos] = Shared.DIR_PREFIX + displayName;
} else {
stringValues[pos] = displayName;
}
@@ -227,7 +228,7 @@
final String lhs = pivotValue;
final String rhs = sortKey[mid];
- final int compare = DocumentInfo.compareToIgnoreCaseNullable(lhs, rhs);
+ final int compare = Shared.compareToIgnoreCaseNullable(lhs, rhs);
if (compare < 0) {
right = mid;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 1c696ad..e9fdab0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -26,7 +26,6 @@
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsProvider;
import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.RootCursorWrapper;
@@ -38,7 +37,6 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ProtocolException;
-import java.text.Collator;
import java.util.Objects;
/**
@@ -48,13 +46,6 @@
private static final int VERSION_INIT = 1;
private static final int VERSION_SPLIT_URI = 2;
- private static final Collator sCollator;
-
- static {
- sCollator = Collator.getInstance();
- sCollator.setStrength(Collator.SECONDARY);
- }
-
public String authority;
public String documentId;
public String mimeType;
@@ -320,31 +311,4 @@
fnfe.initCause(t);
throw fnfe;
}
-
- /**
- * String prefix used to indicate the document is a directory.
- */
- public static final char DIR_PREFIX = '\001';
-
- /**
- * Compare two strings against each other using system default collator in a
- * case-insensitive mode. Clusters strings prefixed with {@link #DIR_PREFIX}
- * before other items.
- */
- public static int compareToIgnoreCaseNullable(String lhs, String rhs) {
- final boolean leftEmpty = TextUtils.isEmpty(lhs);
- final boolean rightEmpty = TextUtils.isEmpty(rhs);
-
- if (leftEmpty && rightEmpty) return 0;
- if (leftEmpty) return -1;
- if (rightEmpty) return 1;
-
- final boolean leftDir = (lhs.charAt(0) == DIR_PREFIX);
- final boolean rightDir = (rhs.charAt(0) == DIR_PREFIX);
-
- if (leftDir && !rightDir) return -1;
- if (rightDir && !leftDir) return 1;
-
- return sCollator.compare(lhs, rhs);
- }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index 3f4a1df..3897058 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -16,10 +16,12 @@
package com.android.documentsui.model;
+import static com.android.documentsui.Shared.compareToIgnoreCaseNullable;
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
+import android.annotation.IntDef;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
@@ -36,17 +38,31 @@
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.net.ProtocolException;
import java.util.Objects;
/**
* Representation of a {@link Root}.
*/
-public class RootInfo implements Durable, Parcelable {
+public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
private static final int VERSION_INIT = 1;
private static final int VERSION_DROP_TYPE = 2;
// The values of these constants determine the sort order of various roots in the RootsFragment.
+ @IntDef(flag = true, value = {
+ TYPE_IMAGES,
+ TYPE_VIDEO,
+ TYPE_AUDIO,
+ TYPE_RECENTS,
+ TYPE_DOWNLOADS,
+ TYPE_LOCAL,
+ TYPE_MTP,
+ TYPE_OTHER
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RootType {}
public static final int TYPE_IMAGES = 1;
public static final int TYPE_VIDEO = 2;
public static final int TYPE_AUDIO = 3;
@@ -69,7 +85,7 @@
/** Derived fields that aren't persisted */
public String[] derivedMimeTypes;
public int derivedIcon;
- public int derivedType;
+ public @RootType int derivedType;
public RootInfo() {
reset();
@@ -329,6 +345,22 @@
}
@Override
+ public int compareTo(RootInfo other) {
+ // Sort by root type, then title, then summary.
+ int score = derivedType - other.derivedType;
+ if (score != 0) {
+ return score;
+ }
+
+ score = compareToIgnoreCaseNullable(title, other.title);
+ if (score != 0) {
+ return score;
+ }
+
+ return compareToIgnoreCaseNullable(summary, other.summary);
+ }
+
+ @Override
public String toString() {
return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
index 83299f0..4b0bc41 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
@@ -28,6 +28,7 @@
import com.android.documentsui.DirectoryResult;
import com.android.documentsui.RootCursorWrapper;
+import com.android.documentsui.Shared;
import com.android.documentsui.State;
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
import com.android.documentsui.model.DocumentInfo;
@@ -190,7 +191,7 @@
assertEquals(ITEM_COUNT, seen.cardinality());
for (int i = 0; i < names.size()-1; ++i) {
- assertTrue(DocumentInfo.compareToIgnoreCaseNullable(names.get(i), names.get(i+1)) <= 0);
+ assertTrue(Shared.compareToIgnoreCaseNullable(names.get(i), names.get(i+1)) <= 0);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index c44b638..6d29c5f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -113,6 +113,12 @@
return admin;
}
+ public static boolean hasBaseUserRestriction(Context context,
+ String userRestriction, int userId) {
+ UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ return um.hasBaseUserRestriction(userRestriction, UserHandle.of(userId));
+ }
+
/**
* Checks if keyguard features are disabled by policy.
*
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 9bd4eb1..227b1e8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -70,6 +70,12 @@
}
}
mAttrUserRestriction = data == null ? null : data.toString();
+ // If the system has set the user restriction, then we shouldn't add the padlock.
+ if (RestrictedLockUtils.hasBaseUserRestriction(mContext, mAttrUserRestriction,
+ UserHandle.myUserId())) {
+ mAttrUserRestriction = null;
+ return;
+ }
final TypedValue useAdminDisabledSummary =
attributes.peekValue(R.styleable.RestrictedPreference_useAdminDisabledSummary);
diff --git a/packages/SystemUI/res/layout/notification_guts.xml b/packages/SystemUI/res/layout/notification_guts.xml
index e550d9c..4d0eb96 100644
--- a/packages/SystemUI/res/layout/notification_guts.xml
+++ b/packages/SystemUI/res/layout/notification_guts.xml
@@ -126,27 +126,6 @@
android:tint="@color/notification_guts_icon_tint" />
</FrameLayout>
-
- <RadioGroup
- android:id="@+id/apply_to"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
- <RadioButton android:id="@+id/apply_to_topic"
- android:layout_width="wrap_content"
- android:layout_height="48dp"
- style="@style/TextAppearance.NotificationGuts.Primary"
- android:visibility="gone"
- android:buttonTint="#858383"
- />
- <RadioButton android:id="@+id/apply_to_app"
- android:layout_width="wrap_content"
- android:layout_height="48dp"
- android:text="@string/apply_to_app"
- style="@style/TextAppearance.NotificationGuts.Primary"
- android:visibility="gone"
- android:buttonTint="#858383"
- />
- </RadioGroup>
</LinearLayout>
<!-- buttons -->
<LinearLayout
diff --git a/packages/SystemUI/res/layout/notification_settings_icon_row.xml b/packages/SystemUI/res/layout/notification_settings_icon_row.xml
new file mode 100644
index 0000000..74f6f9d
--- /dev/null
+++ b/packages/SystemUI/res/layout/notification_settings_icon_row.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2016, 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.
+-->
+<com.android.systemui.statusbar.NotificationSettingsIconRow
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ >
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/gear_icon"
+ android:layout_width="@dimen/notification_gear_size"
+ android:layout_height="@dimen/notification_gear_size"
+ android:layout_marginTop="@dimen/notification_gear_top_margin"
+ android:layout_marginStart="@dimen/notification_gear_side_margin"
+ android:layout_marginEnd="@dimen/notification_gear_side_margin"
+ android:src="@drawable/ic_settings"
+ android:tint="@color/notification_gear_color"
+ android:visibility="gone"
+ android:alpha="0"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ />
+
+</com.android.systemui.statusbar.NotificationSettingsIconRow>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 62fdd42..045ede3 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -23,6 +23,14 @@
android:clickable="true"
>
+ <ViewStub
+ android:layout="@layout/notification_settings_icon_row"
+ android:id="@+id/settings_icon_row_stub"
+ android:inflatedId="@+id/notification_settings_icon_row"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
<com.android.systemui.statusbar.NotificationBackgroundView
android:id="@+id/backgroundNormal"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 4cd920a..8f69bbb 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -102,6 +102,9 @@
<!-- The color of the circle around the primary user in the user switcher -->
<color name="current_user_border_color">@color/system_accent_color</color>
+ <!-- The color of the gear shown behind a notification -->
+ <color name="notification_gear_color">#ff757575</color>
+
<!-- The "inside" of a notification, reached via longpress -->
<color name="notification_guts_bg_color">#eeeeee</color>
<color name="notification_guts_slider_color">@*android:color/material_deep_teal_500</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b8044ba..8c93e2a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -78,6 +78,15 @@
<!-- Minimum layouted height of a notification in the statusbar-->
<dimen name="min_notification_layout_height">48dp</dimen>
+ <!-- Size of gear icon displayed behind a notification -->
+ <dimen name="notification_gear_size">24dp</dimen>
+
+ <!-- The space above the gear icon displayed behind a notification -->
+ <dimen name="notification_gear_top_margin">30dp</dimen>
+
+ <!-- The space on either side of the gear icon displayed behind a notification -->
+ <dimen name="notification_gear_side_margin">20dp</dimen>
+
<!-- size at which Notification icons will be drawn in the status bar -->
<dimen name="status_bar_icon_drawing_size">17dip</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 33b43fe..33f3c30 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -69,9 +69,9 @@
private float mPerpendicularInitialTouchPos;
private boolean mDragging;
private View mCurrView;
- private View mCurrAnimView;
private boolean mCanCurrViewBeDimissed;
private float mDensityScale;
+ private float mTranslation = 0;
private boolean mLongPressSent;
private LongPressListener mLongPressListener;
@@ -121,7 +121,7 @@
return mSwipeDirection == X ? ev.getY() : ev.getX();
}
- private float getTranslation(View v) {
+ protected float getTranslation(View v) {
return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY();
}
@@ -130,7 +130,7 @@
vt.getYVelocity();
}
- private ObjectAnimator createTranslationAnimation(View v, float newPos) {
+ protected ObjectAnimator createTranslationAnimation(View v, float newPos) {
ObjectAnimator anim = ObjectAnimator.ofFloat(v,
mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos);
return anim;
@@ -141,7 +141,17 @@
vt.getXVelocity();
}
- private void setTranslation(View v, float translate) {
+ protected Animator getViewTranslationAnimator(View v, float target,
+ AnimatorUpdateListener listener) {
+ ObjectAnimator anim = createTranslationAnimation(v, target);
+ anim.addUpdateListener(listener);
+ return anim;
+ }
+
+ protected void setTranslation(View v, float translate) {
+ if (v == null) {
+ return;
+ }
if (mSwipeDirection == X) {
v.setTranslationX(translate);
} else {
@@ -237,15 +247,16 @@
mTouchAboveFalsingThreshold = false;
mDragging = false;
mLongPressSent = false;
- mCurrView = mCallback.getChildAtPosition(ev);
mVelocityTracker.clear();
+ mCurrView = mCallback.getChildAtPosition(ev);
+
if (mCurrView != null) {
- mCurrAnimView = mCallback.getChildContentView(mCurrView);
+ onDownUpdate(mCurrView);
mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
mVelocityTracker.addMovement(ev);
mInitialTouchPos = getPos(ev);
mPerpendicularInitialTouchPos = getPerpendicularPos(ev);
-
+ mTranslation = getTranslation(mCurrView);
if (mLongPressListener != null) {
if (mWatchLongPress == null) {
mWatchLongPress = new Runnable() {
@@ -268,7 +279,6 @@
}
mHandler.postDelayed(mWatchLongPress, mLongPressTimeout);
}
-
}
break;
@@ -283,8 +293,8 @@
&& Math.abs(delta) > Math.abs(deltaPerpendicular)) {
mCallback.onBeginDrag(mCurrView);
mDragging = true;
- mInitialTouchPos = getPos(ev) - getTranslation(mCurrAnimView);
-
+ mInitialTouchPos = getPos(ev);
+ mTranslation = getTranslation(mCurrView);
removeLongPressCallback();
}
}
@@ -295,7 +305,6 @@
final boolean captured = (mDragging || mLongPressSent);
mDragging = false;
mCurrView = null;
- mCurrAnimView = null;
mLongPressSent = false;
removeLongPressCallback();
if (captured) return true;
@@ -320,12 +329,11 @@
* @param useAccelerateInterpolator Should an accelerating Interpolator be used
* @param fixedDuration If not 0, this exact duration will be taken
*/
- public void dismissChild(final View view, float velocity, final Runnable endAction,
+ public void dismissChild(final View animView, float velocity, final Runnable endAction,
long delay, boolean useAccelerateInterpolator, long fixedDuration) {
- final View animView = mCallback.getChildContentView(view);
- final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
+ final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
float newPos;
- boolean isLayoutRtl = view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+ boolean isLayoutRtl = animView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
if (velocity < 0
|| (velocity == 0 && getTranslation(animView) < 0)
@@ -355,7 +363,13 @@
if (!mDisableHwLayers) {
animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
- ObjectAnimator anim = createTranslationAnimation(animView, newPos);
+ AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
+ }
+ };
+
+ Animator anim = getViewTranslationAnimator(animView, newPos, updateListener);
if (useAccelerateInterpolator) {
anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
} else {
@@ -367,8 +381,8 @@
}
anim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
- updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
- mCallback.onChildDismissed(view);
+ updateSwipeProgressFromOffset(animView, canBeDismissed);
+ mCallback.onChildDismissed(animView);
if (endAction != null) {
endAction.run();
}
@@ -377,11 +391,6 @@
}
}
});
- anim.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
- updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
- }
- });
prepareDismissAnimation(animView, anim);
anim.start();
}
@@ -393,21 +402,21 @@
// Do nothing
}
- public void snapChild(final View view, float velocity) {
- final View animView = mCallback.getChildContentView(view);
- final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(animView);
- ObjectAnimator anim = createTranslationAnimation(animView, 0);
+ public void snapChild(final View animView, final float targetLeft, float velocity) {
+ final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
+ AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
+ }
+ };
+
+ Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener);
int duration = SNAP_ANIM_LEN;
anim.setDuration(duration);
- anim.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
- updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
- }
- });
anim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animator) {
- updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
- mCallback.onChildSnappedBack(animView);
+ updateSwipeProgressFromOffset(animView, canBeDismissed);
+ mCallback.onChildSnappedBack(animView, targetLeft);
}
});
prepareSnapBackAnimation(animView, anim);
@@ -421,6 +430,28 @@
// Do nothing
}
+ /**
+ * Called when there's a down event.
+ */
+ public void onDownUpdate(View currView) {
+ // Do nothing
+ }
+
+ /**
+ * Called on a move event.
+ */
+ protected void onMoveUpdate(View view, float totalTranslation, float delta) {
+ // Do nothing
+ }
+
+ /**
+ * Called in {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)} when the current
+ * view is being animated to dismiss or snap.
+ */
+ public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) {
+ updateSwipeProgressFromOffset(animView, canBeDismissed);
+ }
+
public boolean onTouchEvent(MotionEvent ev) {
if (mLongPressSent) {
return true;
@@ -456,17 +487,18 @@
// don't let items that can't be dismissed be dragged more than
// maxScrollDistance
if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) {
- float size = getSize(mCurrAnimView);
- float maxScrollDistance = 0.15f * size;
+ float size = getSize(mCurrView);
+ float maxScrollDistance = 0.25f * size;
if (absDelta >= size) {
delta = delta > 0 ? maxScrollDistance : -maxScrollDistance;
} else {
delta = maxScrollDistance * (float) Math.sin((delta/size)*(Math.PI/2));
}
}
- setTranslation(mCurrAnimView, delta);
- updateSwipeProgressFromOffset(mCurrAnimView, mCanCurrViewBeDimissed);
+ setTranslation(mCurrView, mTranslation + delta);
+ updateSwipeProgressFromOffset(mCurrView, mCanCurrViewBeDimissed);
+ onMoveUpdate(mCurrView, mTranslation + delta, delta);
}
break;
case MotionEvent.ACTION_UP:
@@ -478,12 +510,13 @@
float velocity = getVelocity(mVelocityTracker);
float perpendicularVelocity = getPerpendicularVelocity(mVelocityTracker);
+ float translation = getTranslation(mCurrView);
// Decide whether to dismiss the current view
boolean childSwipedFarEnough = DISMISS_IF_SWIPED_FAR_ENOUGH &&
- Math.abs(getTranslation(mCurrAnimView)) > 0.4 * getSize(mCurrAnimView);
+ Math.abs(translation) > 0.4 * getSize(mCurrView);
boolean childSwipedFastEnough = (Math.abs(velocity) > escapeVelocity) &&
(Math.abs(velocity) > Math.abs(perpendicularVelocity)) &&
- (velocity > 0) == (getTranslation(mCurrAnimView) > 0);
+ (velocity > 0) == (translation > 0);
boolean falsingDetected = mCallback.isAntiFalsingNeeded();
if (mFalsingManager.isClassiferEnabled()) {
@@ -502,7 +535,7 @@
} else {
// snappity
mCallback.onDragCancelled(mCurrView);
- snapChild(mCurrView, velocity);
+ snapChild(mCurrView, 0 /* leftTarget */, velocity);
}
}
break;
@@ -518,8 +551,6 @@
public interface Callback {
View getChildAtPosition(MotionEvent ev);
- View getChildContentView(View v);
-
boolean canChildBeDismissed(View v);
boolean isAntiFalsingNeeded();
@@ -530,7 +561,13 @@
void onDragCancelled(View v);
- void onChildSnappedBack(View animView);
+ /**
+ * Called when the child is snapped to a position.
+ *
+ * @param animView the view that was snapped.
+ * @param targetLeft the left position the view was snapped to.
+ */
+ void onChildSnappedBack(View animView, float targetLeft);
/**
* Updates the swipe progress on a child.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 53abe37..5e653dd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -329,7 +329,8 @@
final View.OnLongClickListener longClick = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
- return false;
+ r.tile.longClick();
+ return true;
}
};
r.tileView.init(click, longClick);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 6b94195..f02424b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -212,9 +212,11 @@
}
protected void handleLongClick() {
- // optional
+ mHost.startActivityDismissingKeyguard(getLongClickIntent());
}
+ public abstract Intent getLongClickIntent();
+
protected void handleClearState() {
mTmpState = newTileState();
mState = newTileState();
@@ -279,10 +281,11 @@
mCallbacks.clear();
}
- protected void checkIfRestrictionEnforced(State state, String userRestriction) {
+ protected void checkIfRestrictionEnforcedByAdminOnly(State state, String userRestriction) {
EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
userRestriction, ActivityManager.getCurrentUser());
- if (admin != null) {
+ if (admin != null && !RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ userRestriction, ActivityManager.getCurrentUser())) {
state.disabledByPolicy = true;
state.enforcedAdmin = admin;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
index 1a854c2..f74117c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
@@ -77,6 +77,7 @@
public void init(OnClickListener click, OnLongClickListener longClick) {
setClickable(true);
setOnClickListener(click);
+ setOnLongClickListener(longClick);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 0d5d115..523792b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -84,11 +84,6 @@
addView(view);
}
- public void init(OnClickListener clickPrimary, OnLongClickListener longClick) {
- setOnClickListener(clickPrimary);
- setOnLongClickListener(longClick);
- }
-
protected void handleStateChanged(QSTile.State state) {
super.handleStateChanged(state);
mLabel.setText(state.label);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 3cd9e67..0709992 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -15,13 +15,18 @@
*/
package com.android.systemui.qs.external;
+import android.app.ActivityManager;
import android.content.ComponentName;
+import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
+import android.provider.Settings;
import android.service.quicksettings.IQSTileService;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
@@ -156,8 +161,22 @@
}
@Override
- protected void handleUserSwitch(int newUserId) {
- super.handleUserSwitch(newUserId);
+ public Intent getLongClickIntent() {
+ Intent i = new Intent(TileService.ACTION_QS_TILE_PREFERENCES);
+ i.setPackage(mComponent.getPackageName());
+ i = resolveIntent(i);
+ if (i != null) {
+ return i;
+ }
+ return new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(
+ Uri.fromParts("package", mComponent.getPackageName(), null));
+ }
+
+ private Intent resolveIntent(Intent i) {
+ ResolveInfo result = mContext.getPackageManager().resolveActivityAsUser(i, 0,
+ ActivityManager.getCurrentUser());
+ return result != null ? new Intent(TileService.ACTION_QS_TILE_PREFERENCES)
+ .setClassName(result.activityInfo.packageName, result.activityInfo.name) : null;
}
@Override
@@ -184,10 +203,6 @@
}
@Override
- protected void handleLongClick() {
- }
-
- @Override
protected void handleUpdateState(State state, Object arg) {
Drawable drawable = mTile.getIcon().loadDrawable(mContext);
int color = mContext.getColor(getColor(mTile.getState()));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 5222e61..f0860fe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -21,6 +21,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
+import android.provider.Settings;
import android.provider.Settings.Global;
import com.android.internal.logging.MetricsLogger;
@@ -68,6 +69,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
final int value = arg instanceof Integer ? (Integer)arg : mSetting.getValue();
final boolean airplaneMode = value != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 6a9d826..93e075d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -19,6 +19,7 @@
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.provider.Settings;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.RelativeSizeSpan;
@@ -91,6 +92,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
+ }
+
+ @Override
protected void handleClick() {
showDetail(true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index c4b7944..80f667c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -78,6 +78,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
+ }
+
+ @Override
protected void handleClick() {
if (!mController.canConfigBluetooth()) {
mHost.startActivityDismissingKeyguard(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 15e082a..e0ad002 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -86,6 +86,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_CAST_SETTINGS);
+ }
+
+ @Override
protected void handleClick() {
if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
mHost.startRunnableDismissingKeyguard(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 15617c7f..5f87741 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -37,7 +37,7 @@
/** Quick settings tile: Cellular **/
public class CellularTile extends QSTile<QSTile.SignalState> {
- private static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName(
+ static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName(
"com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
private final NetworkController mController;
@@ -78,6 +78,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return CELLULAR_SETTINGS;
+ }
+
+ @Override
protected void handleClick() {
MetricsLogger.action(mContext, getMetricsCategory());
if (mDataController.isMobileDataSupported()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index e98734c..42ce69c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -16,6 +16,8 @@
package com.android.systemui.qs.tiles;
+import android.content.Intent;
+import android.provider.Settings;
import android.provider.Settings.Secure;
import com.android.internal.logging.MetricsLogger;
@@ -70,6 +72,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
+ }
+
+ @Override
protected void handleClick() {
MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
mSetting.setValue(mState.value ? 0 : 1);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index c6a98b4..a1789a5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -14,6 +14,7 @@
package com.android.systemui.qs.tiles;
+import android.content.Intent;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
@@ -44,6 +45,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return CellularTile.CELLULAR_SETTINGS;
+ }
+
+ @Override
protected void handleClick() {
mState.value = !mDataSaverController.isDataSaverEnabled();
mDataSaverController.setDataSaverEnabled(mState.value);
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 29ca06b..8982b3e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -29,11 +29,13 @@
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
+import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.Prefs;
import com.android.systemui.R;
+import com.android.systemui.SysUIToast;
import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.volume.ZenModePanel;
@@ -99,7 +101,20 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return ZEN_SETTINGS;
+ }
+
+ @Override
public void handleClick() {
+ if (mController.isVolumeRestricted()) {
+ // Collapse the panels, so the user can see the toast.
+ mHost.collapsePanels();
+ SysUIToast.makeText(mContext, mContext.getString(
+ com.android.internal.R.string.error_message_change_not_allowed),
+ Toast.LENGTH_LONG).show();
+ return;
+ }
MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
if (mState.value) {
mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
@@ -116,8 +131,7 @@
final boolean newValue = zen != Global.ZEN_MODE_OFF;
final boolean valueChanged = state.value != newValue;
state.value = newValue;
- state.disabledByPolicy = mController.isVolumeRestricted();
- checkIfRestrictionEnforced(state, UserManager.DISALLOW_ADJUST_VOLUME);
+ checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
switch (zen) {
case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index f06634e..c10843a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -18,6 +18,8 @@
import android.app.ActivityManager;
+import android.content.Intent;
+import android.provider.MediaStore;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -60,6 +62,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+ }
+
+ @Override
protected void handleClick() {
if (ActivityManager.isUserAMonkey()) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 943b502..ad1c7a0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -16,8 +16,10 @@
package com.android.systemui.qs.tiles;
+import android.content.Intent;
import android.os.UserManager;
+import android.provider.Settings;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -58,6 +60,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_WIRELESS_SETTINGS);
+ }
+
+ @Override
protected void handleClick() {
final boolean isEnabled = (Boolean) mState.value;
MetricsLogger.action(mContext, getMetricsCategory(), !isEnabled);
@@ -68,8 +75,7 @@
protected void handleUpdateState(BooleanState state, Object arg) {
state.label = mContext.getString(R.string.quick_settings_hotspot_label);
- state.disabledByPolicy = mController.isTetheringAllowed();
- checkIfRestrictionEnforced(state, UserManager.DISALLOW_CONFIG_TETHERING);
+ checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_TETHERING);
if (arg instanceof Boolean) {
state.value = (boolean) arg;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index bdf95d8..bb5ff8e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -92,6 +92,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return null;
+ }
+
+ @Override
protected void handleLongClick() {
sendIntent("long-click", mOnLongClick, mOnLongClickUri);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 9f41f9a..6533252 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -16,8 +16,10 @@
package com.android.systemui.qs.tiles;
+import android.content.Intent;
import android.os.UserManager;
+import android.provider.Settings;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -61,6 +63,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+ }
+
+ @Override
protected void handleClick() {
if (mKeyguard.isSecure() && mKeyguard.isShowing()) {
mHost.startRunnableDismissingKeyguard(new Runnable() {
@@ -87,8 +94,7 @@
// bug is fixed, this should be reverted to only hiding it on secure lock screens:
// state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
state.value = locationEnabled;
- state.disabledByPolicy = mController.isUserLocationRestricted();
- checkIfRestrictionEnforced(state, UserManager.DISALLOW_SHARE_LOCATION);
+ checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_SHARE_LOCATION);
if (locationEnabled) {
state.icon = mEnable;
state.label = mContext.getString(R.string.quick_settings_location_label);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index c94cf5a..b267ccd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -17,8 +17,10 @@
package com.android.systemui.qs.tiles;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Configuration;
+import android.provider.Settings;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -60,6 +62,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_DISPLAY_SETTINGS);
+ }
+
+ @Override
protected void handleClick() {
if (mController == null) return;
MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
index ba7ea4d..f1066c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
@@ -16,7 +16,9 @@
package com.android.systemui.qs.tiles;
import android.content.Context;
+import android.content.Intent;
import android.graphics.drawable.Drawable;
+import android.provider.Settings;
import android.util.Pair;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -42,6 +44,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_USER_SETTINGS);
+ }
+
+ @Override
protected void handleClick() {
showDetail(true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 7a58f15..7ee795f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -93,6 +93,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return WIFI_SETTINGS;
+ }
+
+ @Override
protected void handleSecondaryClick() {
// Secondary clicks are header clicks, just toggle.
mState.copyTo(mStateBeforeClick);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 053a98a..003e9c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -16,6 +16,8 @@
package com.android.systemui.qs.tiles;
+import android.content.Intent;
+import android.provider.Settings;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -52,6 +54,11 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_SYNC_SETTINGS);
+ }
+
+ @Override
public void handleClick() {
MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
mProfileController.setWorkModeEnabled(!mState.value);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index fe504fe..3f0630d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -494,7 +494,7 @@
* onChildDismissed() calls.
*/
@Override
- public void onChildSnappedBack(View v) {
+ public void onChildSnappedBack(View v, float targetLeft) {
TaskView tv = (TaskView) v;
// Re-enable clipping with the stack
@@ -517,11 +517,6 @@
}
@Override
- public View getChildContentView(View v) {
- return v;
- }
-
- @Override
public boolean isAntiFalsingNeeded() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 2bebac2..411fd08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -103,6 +103,7 @@
import com.android.systemui.statusbar.policy.PreviewInflater;
import com.android.systemui.statusbar.policy.RemoteInputView;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.GearDisplayedListener;
import com.android.systemui.statusbar.stack.StackStateAnimator;
import java.util.ArrayList;
@@ -115,7 +116,7 @@
public abstract class BaseStatusBar extends SystemUI implements
CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener,
ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment,
- ExpandableNotificationRow.OnExpandClickListener {
+ ExpandableNotificationRow.OnExpandClickListener, GearDisplayedListener {
public static final String TAG = "StatusBar";
public static final boolean DEBUG = false;
public static final boolean MULTIUSER_DEBUG = false;
@@ -220,6 +221,7 @@
// which notification is currently being longpress-examined by the user
private NotificationGuts mNotificationGutsExposed;
+ private ExpandableNotificationRow mNotificationGearDisplayed;
private KeyboardShortcuts mKeyboardShortcuts;
@@ -1008,6 +1010,10 @@
guts.bindImportance(sbn, row, mNotificationData.getImportance(sbn.getKey()));
}
+ protected GearDisplayedListener getGearDisplayedListener() {
+ return this;
+ }
+
protected SwipeHelper.LongPressListener getNotificationLongClicker() {
return new SwipeHelper.LongPressListener() {
@Override
@@ -1020,7 +1026,7 @@
return false;
}
- ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+ final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
bindGuts(row);
// Assume we are a status_bar_notification_row
@@ -1052,6 +1058,14 @@
= ViewAnimationUtils.createCircularReveal(guts, x, y, 0, r);
a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
a.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+ a.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ // Move the notification view back over the gear
+ row.resetTranslation();
+ }
+ });
a.start();
guts.setExposed(true);
mStackScroller.onHeightChanged(null, true /* needsAnimation */);
@@ -1063,6 +1077,11 @@
};
}
+ @Override
+ public void onGearDisplayed(ExpandableNotificationRow row) {
+ mNotificationGearDisplayed = row;
+ }
+
public void dismissPopups() {
dismissPopups(-1, -1);
}
@@ -1095,6 +1114,11 @@
v.setExposed(false);
mStackScroller.onHeightChanged(null, true /* needsAnimation */);
}
+
+ if (mNotificationGearDisplayed != null) {
+ mNotificationGearDisplayed.resetTranslation();
+ mNotificationGearDisplayed = null;
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 7422902e..94511da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -16,6 +16,12 @@
package com.android.systemui.statusbar;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Notification;
import android.content.Context;
import android.graphics.drawable.AnimatedVectorDrawable;
@@ -45,6 +51,7 @@
import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.statusbar.stack.StackViewState;
+import java.util.ArrayList;
import java.util.List;
public class ExpandableNotificationRow extends ActivatableNotificationView {
@@ -87,6 +94,8 @@
*/
private boolean mOnKeyguard;
+ private AnimatorSet mTranslateAnim;
+ private ArrayList<View> mTranslateableViews;
private NotificationContentView mPublicLayout;
private NotificationContentView mPrivateLayout;
private int mMaxExpandHeight;
@@ -96,6 +105,7 @@
private ExpansionLogger mLogger;
private String mLoggingKey;
private boolean mWasReset;
+ private NotificationSettingsIconRow mSettingsIconRow;
private NotificationGuts mGuts;
private NotificationData.Entry mEntry;
private StatusBarNotification mStatusBarNotification;
@@ -108,6 +118,7 @@
private boolean mChildrenExpanded;
private boolean mIsSummaryWithChildren;
private NotificationChildrenContainer mChildrenContainer;
+ private ViewStub mSettingsIconRowStub;
private ViewStub mGutsStub;
private boolean mIsSystemChildExpanded;
private boolean mIsPinned;
@@ -527,6 +538,17 @@
mGuts.setVisibility(oldGuts.getVisibility());
addView(mGuts, index);
}
+ if (mSettingsIconRow != null) {
+ View oldSettings = mSettingsIconRow;
+ int settingsIndex = indexOfChild(oldSettings);
+ removeView(oldSettings);
+ mSettingsIconRow = (NotificationSettingsIconRow) LayoutInflater.from(mContext).inflate(
+ R.layout.notification_settings_icon_row, this, false);
+ mSettingsIconRow.setNotificationRowParent(ExpandableNotificationRow.this);
+ mSettingsIconRow.setVisibility(oldSettings.getVisibility());
+ addView(mSettingsIconRow, settingsIndex);
+
+ }
mPrivateLayout.reInflateViews();
mPublicLayout.reInflateViews();
}
@@ -573,6 +595,7 @@
mPublicLayout.reset(mIsHeadsUp);
mPrivateLayout.reset(mIsHeadsUp);
resetHeight();
+ resetTranslation();
logExpansionEvent(false, wasExpanded);
}
@@ -596,6 +619,14 @@
mPrivateLayout.setExpandClickListener(mExpandClickListener);
mPrivateLayout.setContainingNotification(this);
mPublicLayout.setExpandClickListener(mExpandClickListener);
+ mSettingsIconRowStub = (ViewStub) findViewById(R.id.settings_icon_row_stub);
+ mSettingsIconRowStub.setOnInflateListener(new ViewStub.OnInflateListener() {
+ @Override
+ public void onInflate(ViewStub stub, View inflated) {
+ mSettingsIconRow = (NotificationSettingsIconRow) inflated;
+ mSettingsIconRow.setNotificationRowParent(ExpandableNotificationRow.this);
+ }
+ });
mGutsStub = (ViewStub) findViewById(R.id.notification_guts_stub);
mGutsStub.setOnInflateListener(new ViewStub.OnInflateListener() {
@Override
@@ -603,6 +634,7 @@
mGuts = (NotificationGuts) inflated;
mGuts.setClipTopAmount(getClipTopAmount());
mGuts.setActualHeight(getActualHeight());
+ mTranslateableViews.add(mGuts);
mGutsStub = null;
}
});
@@ -613,9 +645,89 @@
public void onInflate(ViewStub stub, View inflated) {
mChildrenContainer = (NotificationChildrenContainer) inflated;
mChildrenContainer.setNotificationParent(ExpandableNotificationRow.this);
+ mTranslateableViews.add(mChildrenContainer);
}
});
mVetoButton = findViewById(R.id.veto);
+
+ // Add the views that we translate to reveal the gear
+ mTranslateableViews = new ArrayList<View>();
+ for (int i = 0; i < getChildCount(); i++) {
+ mTranslateableViews.add(getChildAt(i));
+ }
+ // Remove views that don't translate
+ mTranslateableViews.remove(mVetoButton);
+ mTranslateableViews.remove(mSettingsIconRowStub);
+ mTranslateableViews.remove(mChildrenContainerStub);
+ mTranslateableViews.remove(mGutsStub);
+ }
+
+ public void setTranslationForOutline(float translationX) {
+ setOutlineRect(false, translationX, getTop(), getRight() + translationX, getBottom());
+ }
+
+ public void resetTranslation() {
+ if (mTranslateableViews != null) {
+ for (int i = 0; i < mTranslateableViews.size(); i++) {
+ mTranslateableViews.get(i).setTranslationX(0);
+ }
+ setTranslationForOutline(0);
+ }
+ if (mSettingsIconRow != null) {
+ mSettingsIconRow.resetState();
+ }
+ }
+
+ public void animateTranslateNotification(final float leftTarget) {
+ if (mTranslateAnim != null) {
+ mTranslateAnim.cancel();
+ }
+ AnimatorSet set = new AnimatorSet();
+ if (mTranslateableViews != null) {
+ for (int i = 0; i < mTranslateableViews.size(); i++) {
+ final View animView = mTranslateableViews.get(i);
+ final ObjectAnimator translateAnim = ObjectAnimator.ofFloat(
+ animView, "translationX", leftTarget);
+ if (i == 0) {
+ translateAnim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ setTranslationForOutline((float) animation.getAnimatedValue());
+ }
+ });
+ }
+ translateAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator anim) {
+ if (mSettingsIconRow != null && leftTarget == 0) {
+ mSettingsIconRow.resetState();
+ }
+ mTranslateAnim = null;
+ }
+ });
+ set.play(translateAnim);
+ }
+ }
+ mTranslateAnim = set;
+ set.start();
+ }
+
+ public float getSpaceForGear() {
+ if (mSettingsIconRow != null) {
+ return mSettingsIconRow.getSpaceForGear();
+ }
+ return 0;
+ }
+
+ public NotificationSettingsIconRow getSettingsRow() {
+ if (mSettingsIconRow == null) {
+ mSettingsIconRowStub.inflate();
+ }
+ return mSettingsIconRow;
+ }
+
+ public ArrayList<View> getContentViews() {
+ return mTranslateableViews;
}
public void inflateGuts() {
@@ -772,7 +884,7 @@
if (mIsSummaryWithChildren) {
mChildrenContainer.updateGroupOverflow();
}
- notifyHeightChanged(false /* needsAnimation */);
+ notifyHeightChanged(false /* needsAnimation */);
}
}
}
@@ -1097,6 +1209,7 @@
mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(),
mNotificationHeader);
addView(mNotificationHeader, indexOfChild(mChildrenContainer) + 1);
+ mTranslateableViews.add(mNotificationHeader);
} else {
header.reapply(getContext(), mNotificationHeader);
mNotificationHeaderWrapper.notifyContentUpdated(mEntry.notification);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index 44c6a5d..782a38c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -81,8 +81,13 @@
}
protected void setOutlineRect(float left, float top, float right, float bottom) {
+ setOutlineRect(true, left, top, right, bottom);
+ }
+
+ protected void setOutlineRect(boolean clipToOutline, float left, float top, float right,
+ float bottom) {
mCustomOutline = true;
- setClipToOutline(true);
+ setClipToOutline(clipToOutline);
mOutlineRect.set((int) left, (int) top, (int) right, (int) bottom);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 7346bec..fe84d813 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -49,9 +49,7 @@
private int mClipTopAmount;
private int mActualHeight;
private boolean mExposed;
- private RadioButton mApplyToTopic;
private SeekBar mSeekBar;
- private Notification.Topic mTopic;
private INotificationManager mINotificationManager;
private int mStartingImportance;
@@ -109,24 +107,9 @@
mStartingImportance = importance;
mINotificationManager = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- mTopic = sbn.getNotification().getTopic() == null
- ? new Notification.Topic(Notification.TOPIC_DEFAULT, mContext.getString(
- com.android.internal.R.string.default_notification_topic_label))
- : sbn.getNotification().getTopic();
- boolean doesUserUseTopics = false;
- try {
- doesUserUseTopics =
- mINotificationManager.doesUserUseTopics(sbn.getPackageName(), sbn.getUid());
- } catch (RemoteException e) {}
- final boolean userUsesTopics = doesUserUseTopics;
- mApplyToTopic = (RadioButton) row.findViewById(R.id.apply_to_topic);
- if (userUsesTopics) {
- mApplyToTopic.setChecked(true);
- }
- final View applyToApp = row.findViewById(R.id.apply_to_app);
- final TextView topicSummary = ((TextView) row.findViewById(R.id.summary));
- final TextView topicTitle = ((TextView) row.findViewById(R.id.title));
+ final TextView importanceSummary = ((TextView) row.findViewById(R.id.summary));
+ final TextView importanceTitle = ((TextView) row.findViewById(R.id.title));
mSeekBar = (SeekBar) row.findViewById(R.id.seekbar);
boolean systemApp = false;
try {
@@ -156,12 +139,6 @@
updateTitleAndSummary(progress);
if (fromUser) {
MetricsLogger.action(mContext, MetricsEvent.ACTION_MODIFY_IMPORTANCE_SLIDER);
- if (userUsesTopics) {
- mApplyToTopic.setVisibility(View.VISIBLE);
- mApplyToTopic.setText(
- mContext.getString(R.string.apply_to_topic, mTopic.getLabel()));
- applyToApp.setVisibility(View.VISIBLE);
- }
}
}
@@ -178,29 +155,29 @@
private void updateTitleAndSummary(int progress) {
switch (progress) {
case NotificationListenerService.Ranking.IMPORTANCE_NONE:
- topicSummary.setText(mContext.getString(
+ importanceSummary.setText(mContext.getString(
R.string.notification_importance_blocked));
- topicTitle.setText(mContext.getString(R.string.blocked_importance));
+ importanceTitle.setText(mContext.getString(R.string.blocked_importance));
break;
case NotificationListenerService.Ranking.IMPORTANCE_LOW:
- topicSummary.setText(mContext.getString(
+ importanceSummary.setText(mContext.getString(
R.string.notification_importance_low));
- topicTitle.setText(mContext.getString(R.string.low_importance));
+ importanceTitle.setText(mContext.getString(R.string.low_importance));
break;
case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT:
- topicSummary.setText(mContext.getString(
+ importanceSummary.setText(mContext.getString(
R.string.notification_importance_default));
- topicTitle.setText(mContext.getString(R.string.default_importance));
+ importanceTitle.setText(mContext.getString(R.string.default_importance));
break;
case NotificationListenerService.Ranking.IMPORTANCE_HIGH:
- topicSummary.setText(mContext.getString(
+ importanceSummary.setText(mContext.getString(
R.string.notification_importance_high));
- topicTitle.setText(mContext.getString(R.string.high_importance));
+ importanceTitle.setText(mContext.getString(R.string.high_importance));
break;
case NotificationListenerService.Ranking.IMPORTANCE_MAX:
- topicSummary.setText(mContext.getString(
+ importanceSummary.setText(mContext.getString(
R.string.notification_importance_max));
- topicTitle.setText(mContext.getString(R.string.max_importance));
+ importanceTitle.setText(mContext.getString(R.string.max_importance));
break;
}
}
@@ -213,8 +190,7 @@
MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
progress - mStartingImportance);
try {
- mINotificationManager.setImportance(sbn.getPackageName(), sbn.getUid(),
- mApplyToTopic.isChecked() ? mTopic : null, progress);
+ mINotificationManager.setImportance(sbn.getPackageName(), sbn.getUid(), progress);
} catch (RemoteException e) {
// :(
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java
new file mode 100644
index 0000000..8fcd455
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2016 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;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+
+public class NotificationSettingsIconRow extends FrameLayout implements View.OnClickListener {
+
+ public interface SettingsIconRowListener {
+ /**
+ * Called when the gear behind a notification is touched.
+ */
+ public void onGearTouched(ExpandableNotificationRow row);
+ }
+
+ private ExpandableNotificationRow mParent;
+ private AlphaOptimizedImageView mGearIcon;
+ private float mHorizSpaceForGear;
+ private SettingsIconRowListener mListener;
+
+ private ValueAnimator mFadeAnimator;
+ private boolean mSettingsFadedIn = false;
+ private boolean mAnimating = false;
+ private boolean mOnLeft = true;
+
+ public NotificationSettingsIconRow(Context context) {
+ this(context, null);
+ }
+
+ public NotificationSettingsIconRow(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public NotificationSettingsIconRow(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public NotificationSettingsIconRow(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mGearIcon = (AlphaOptimizedImageView) findViewById(R.id.gear_icon);
+ mGearIcon.setOnClickListener(this);
+
+ final float iconMargin =
+ ((ViewGroup.MarginLayoutParams) mGearIcon.getLayoutParams()).getMarginStart();
+ final float iconWidth =
+ getResources().getDimensionPixelOffset(R.dimen.notification_gear_size);
+ mHorizSpaceForGear = (iconWidth + iconMargin * 2);
+ resetState();
+ }
+
+ public void setGearListener(SettingsIconRowListener listener) {
+ mListener = listener;
+ }
+
+ public void setNotificationRowParent(ExpandableNotificationRow parent) {
+ mParent = parent;
+ }
+
+ public ExpandableNotificationRow getNotificationParent() {
+ return mParent;
+ }
+
+ public void resetState() {
+ setGearAlpha(0f);
+ mAnimating = false;
+ setIconLocation(true /* on left */);
+ }
+
+ private void setGearAlpha(float alpha) {
+ if (alpha == 0) {
+ mSettingsFadedIn = false; // Can fade in again once it's gone.
+ mGearIcon.setVisibility(View.INVISIBLE);
+ } else {
+ if (alpha == 1) {
+ mSettingsFadedIn = true;
+ }
+ mGearIcon.setVisibility(View.VISIBLE);
+ }
+ mGearIcon.setAlpha(alpha);
+ }
+
+ /**
+ * Returns the horizontal space in pixels required to display the gear behind a notification.
+ */
+ public float getSpaceForGear() {
+ return mHorizSpaceForGear;
+ }
+
+ /**
+ * Indicates whether the gear is visible at 1 alpha. Does not indicate
+ * if entire view is visible.
+ */
+ public boolean isVisible() {
+ return mSettingsFadedIn;
+ }
+
+ public void cancelFadeAnimator() {
+ if (mFadeAnimator != null) {
+ mFadeAnimator.cancel();
+ }
+ }
+
+ public void updateSettingsIcons(final float transX, final float size) {
+ if (mAnimating || (mGearIcon.getAlpha() == 0)) {
+ // Don't adjust when animating or settings aren't visible
+ return;
+ }
+ setIconLocation(transX > 0 /* fromLeft */);
+ final float fadeThreshold = size * 0.3f;
+ final float absTrans = Math.abs(transX);
+ float desiredAlpha = 0;
+
+ // if ((fromLeft && transX <= fadeThreshold) || (!fromLeft && absTrans <= fadeThreshold)) {
+ if (absTrans <= fadeThreshold) {
+ desiredAlpha = 1;
+ } else {
+ desiredAlpha = 1 - ((absTrans - fadeThreshold) / (size - fadeThreshold));
+ }
+ setGearAlpha(desiredAlpha);
+ }
+
+ public void fadeInSettings(final boolean fromLeft, final float transX,
+ final float notiThreshold) {
+ setIconLocation(transX > 0 /* fromLeft */);
+ mFadeAnimator = ValueAnimator.ofFloat(mGearIcon.getAlpha(), 1);
+ mFadeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final float absTrans = Math.abs(transX);
+
+ boolean pastGear = (fromLeft && transX <= notiThreshold)
+ || (!fromLeft && absTrans <= notiThreshold);
+ if (pastGear && !mSettingsFadedIn) {
+ setGearAlpha((float) animation.getAnimatedValue());
+ }
+ }
+ });
+ mFadeAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ mAnimating = false;
+ mSettingsFadedIn = false;
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ mAnimating = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ mAnimating = false;
+ mSettingsFadedIn = true;
+ }
+ });
+ mFadeAnimator.setInterpolator(Interpolators.ALPHA_IN);
+ mFadeAnimator.setDuration(200);
+ mFadeAnimator.start();
+ }
+
+ @Override
+ public void onClick(View v) {
+ mListener.onGearTouched(mParent);
+ }
+
+ private void setIconLocation(boolean onLeft) {
+ if (onLeft == mOnLeft) {
+ // Same side? Do nothing.
+ return;
+ }
+ mGearIcon.setTranslationX(onLeft ? 0 : (getWidth() - mHorizSpaceForGear));
+ mOnLeft = onLeft;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
new file mode 100644
index 0000000..4f3c61e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2016 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.app.ActivityManager;
+import android.app.IWallpaperManager;
+import android.app.IWallpaperManagerCallback;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import libcore.io.IoUtils;
+
+/**
+ * Manages the lockscreen wallpaper.
+ */
+public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implements Runnable {
+
+ private static final String TAG = "LockscreenWallpaper";
+
+ private final Context mContext;
+ private final PhoneStatusBar mBar;
+ private final IWallpaperManager mService;
+ private final Handler mH;
+
+ private boolean mCached;
+ private Bitmap mCache;
+ private int mUserId;
+
+ public LockscreenWallpaper(Context ctx, PhoneStatusBar bar, Handler h) {
+ mContext = ctx;
+ mBar = bar;
+ mH = h;
+ mService = IWallpaperManager.Stub.asInterface(
+ ServiceManager.getService(Context.WALLPAPER_SERVICE));
+ mUserId = ActivityManager.getCurrentUser();
+
+ try {
+ mService.setLockWallpaperCallback(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "System dead?" + e);
+ }
+ }
+
+ public Bitmap getBitmap() {
+ try {
+ if (mCached) {
+ return mCache;
+ }
+ if (!mService.isWallpaperSupported(mContext.getOpPackageName())) {
+ mCached = true;
+ mCache = null;
+ return null;
+ }
+ ParcelFileDescriptor fd = mService.getWallpaper(null, WallpaperManager.FLAG_SET_LOCK,
+ new Bundle(), mUserId);
+ if (fd != null) {
+ try {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ mCache = BitmapFactory.decodeFileDescriptor(
+ fd.getFileDescriptor(), null, options);
+ mCached = true;
+ return mCache;
+ } catch (OutOfMemoryError e) {
+ Log.w(TAG, "Can't decode file", e);
+ return null;
+ } finally {
+ IoUtils.closeQuietly(fd);
+ }
+ } else {
+ mCached = true;
+ mCache = null;
+ return null;
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "System dead?" + e);
+ return null;
+ }
+ }
+
+ public void setUser(int user) {
+ if (user != mUserId) {
+ mCached = false;
+ mUserId = user;
+ }
+ }
+
+ @Override
+ public void onWallpaperChanged() {
+ // Called on Binder thread.
+ mH.removeCallbacks(this);
+ mH.post(this);
+ }
+
+ @Override
+ public void run() {
+ // Called in response to onWallpaperChanged on the main thread.
+ mCached = false;
+ mCache = null;
+ getBitmap();
+ mBar.updateMediaMetaData(true /* metaDataChanged */, true /* allowEnterAnimation */);
+ }
+}
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 401d405..032957f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -23,6 +23,7 @@
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
+import android.app.IWallpaperManagerCallback;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.StatusBarManager;
@@ -248,9 +249,7 @@
private static final boolean ONLY_CORE_APPS;
/** If true, the lockscreen will show a distinct wallpaper */
- private static final boolean ENABLE_LOCKSCREEN_WALLPAPER =
- !ActivityManager.isLowRamDeviceStatic()
- && SystemProperties.getBoolean("debug.lockscreen_wallpaper", false);
+ private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
/* If true, the device supports freeform window management.
* This affects the status bar UI. */
@@ -296,6 +295,7 @@
AccessibilityController mAccessibilityController;
FingerprintUnlockController mFingerprintUnlockController;
LightStatusBarController mLightStatusBarController;
+ private LockscreenWallpaper mLockscreenWallpaper;
int mNaturalBarHeight = -1;
@@ -746,6 +746,7 @@
mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
R.id.notification_stack_scroller);
mStackScroller.setLongPressListener(getNotificationLongClicker());
+ mStackScroller.setGearDisplayedListener(getGearDisplayedListener());
mStackScroller.setPhoneStatusBar(this);
mStackScroller.setGroupManager(mGroupManager);
mStackScroller.setHeadsUpManager(mHeadsUpManager);
@@ -792,6 +793,10 @@
mKeyguardBottomArea.getLockIcon());
mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
+ if (ENABLE_LOCKSCREEN_WALLPAPER) {
+ mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
+ }
+
// set the initial view visibility
setAreThereNotifications();
@@ -1819,7 +1824,7 @@
};
/**
- * Refresh or remove lockscreen artwork from media metadata.
+ * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
*/
public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) return;
@@ -1847,10 +1852,7 @@
}
}
if (ENABLE_LOCKSCREEN_WALLPAPER && artworkBitmap == null) {
- // TODO: use real lockscreen wallpaper.
- WallpaperManager wallpaperManager = mContext
- .getSystemService(WallpaperManager.class);
- artworkBitmap = wallpaperManager.getBitmap();
+ artworkBitmap = mLockscreenWallpaper.getBitmap();
}
final boolean hasArtwork = artworkBitmap != null;
@@ -3084,10 +3086,6 @@
else if (Intent.ACTION_SCREEN_ON.equals(action)) {
notifyNavigationBarScreenOn(true);
}
- else if (ENABLE_LOCKSCREEN_WALLPAPER
- && Intent.ACTION_WALLPAPER_CHANGED.equals(action)) {
- updateMediaMetaData(true, true);
- }
}
};
@@ -3173,6 +3171,7 @@
resetUserSetupObserver();
setControllerUsers();
clearCurrentMediaNotification();
+ mLockscreenWallpaper.setUser(newUserId);
updateMediaMetaData(true, false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
index 500d603..047f14d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
@@ -21,7 +21,6 @@
void removeCallback(Callback callback);
boolean isHotspotEnabled();
void setHotspotEnabled(boolean enabled);
- boolean isTetheringAllowed();
public interface Callback {
void onHotspotChanged(boolean enabled);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index 07b7409..f03d9e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -16,15 +16,12 @@
package com.android.systemui.statusbar.policy;
-import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
-import android.os.UserHandle;
-import android.os.UserManager;
import android.util.Log;
import java.io.FileDescriptor;
@@ -40,8 +37,6 @@
private final Receiver mReceiver = new Receiver();
private final ConnectivityManager mConnectivityManager;
private final Context mContext;
- private final UserManager mUserManager;
- private final int mCurrentUser;
private int mHotspotState;
@@ -49,8 +44,6 @@
mContext = context;
mConnectivityManager = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
- mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mCurrentUser = ActivityManager.getCurrentUser();
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -95,12 +88,6 @@
return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED;
}
- @Override
- public boolean isTetheringAllowed() {
- return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING,
- UserHandle.of(mCurrentUser));
- }
-
static final class OnStartTetheringCallback extends
ConnectivityManager.OnStartTetheringCallback {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 401943e..29a8981 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -21,7 +21,6 @@
boolean setLocationEnabled(boolean enabled);
void addSettingsChangedCallback(LocationSettingsChangeCallback cb);
void removeSettingsChangedCallback(LocationSettingsChangeCallback cb);
- boolean isUserLocationRestricted();
/**
* A callback for change in location settings (the user has enabled/disabled location).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 436a40d..8d84be4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -52,7 +52,6 @@
private AppOpsManager mAppOpsManager;
private StatusBarManager mStatusBarManager;
- private final int mCurrentUser;
private boolean mAreActiveLocationRequests;
@@ -74,7 +73,6 @@
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mStatusBarManager
= (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
- mCurrentUser = ActivityManager.getCurrentUser();
// Examine the current location state and initialize the status view.
updateActiveLocationRequests();
@@ -105,6 +103,10 @@
* @return true if attempt to change setting was successful.
*/
public boolean setLocationEnabled(boolean enabled) {
+ int currentUserId = ActivityManager.getCurrentUser();
+ if (isUserLocationRestricted(currentUserId)) {
+ return false;
+ }
final ContentResolver cr = mContext.getContentResolver();
// When enabling location, a user consent dialog will pop up, and the
// setting won't be fully enabled until the user accepts the agreement.
@@ -113,7 +115,7 @@
// QuickSettings always runs as the owner, so specifically set the settings
// for the current foreground user.
return Settings.Secure
- .putIntForUser(cr, Settings.Secure.LOCATION_MODE, mode, mCurrentUser);
+ .putIntForUser(cr, Settings.Secure.LOCATION_MODE, mode, currentUserId);
}
/**
@@ -131,10 +133,10 @@
/**
* Returns true if the current user is restricted from using location.
*/
- public boolean isUserLocationRestricted() {
+ private boolean isUserLocationRestricted(int userId) {
final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
return um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION,
- UserHandle.of(mCurrentUser));
+ UserHandle.of(userId));
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 6ca7dc8..13369f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -210,12 +210,16 @@
}
}
+ boolean systemCanCreateUsers = !mUserManager.hasBaseUserRestriction(
+ UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM);
boolean currentUserCanCreateUsers = currentUserInfo != null
&& (currentUserInfo.isAdmin()
- || currentUserInfo.id == UserHandle.USER_SYSTEM);
- boolean canCreateGuest = (currentUserCanCreateUsers || addUsersWhenLocked)
+ || currentUserInfo.id == UserHandle.USER_SYSTEM)
+ && systemCanCreateUsers;
+ boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked;
+ boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers)
&& guestRecord == null;
- boolean canCreateUser = (currentUserCanCreateUsers || addUsersWhenLocked)
+ boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers)
&& mUserManager.canAddMoreUsers();
boolean createIsRestricted = !addUsersWhenLocked;
@@ -225,7 +229,7 @@
guestRecord = new UserRecord(null /* info */, null /* picture */,
true /* isGuest */, false /* isCurrent */,
false /* isAddUser */, createIsRestricted);
- checkIfAddUserDisallowed(guestRecord);
+ checkIfAddUserDisallowedByAdminOnly(guestRecord);
records.add(guestRecord);
}
} else {
@@ -238,7 +242,7 @@
UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
createIsRestricted);
- checkIfAddUserDisallowed(addUserRecord);
+ checkIfAddUserDisallowedByAdminOnly(addUserRecord);
records.add(addUserRecord);
}
@@ -615,10 +619,11 @@
}
}
- private void checkIfAddUserDisallowed(UserRecord record) {
+ private void checkIfAddUserDisallowedByAdminOnly(UserRecord record) {
EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser());
- if (admin != null) {
+ if (admin != null && !RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser())) {
record.isDisabledByAdmin = true;
record.enforcedAdmin = admin;
} else {
@@ -683,7 +688,7 @@
}
public final QSTile.DetailAdapter userDetailAdapter = new QSTile.DetailAdapter() {
- private final Intent USER_SETTINGS_INTENT = new Intent("android.settings.USER_SETTINGS");
+ private final Intent USER_SETTINGS_INTENT = new Intent(Settings.ACTION_USER_SETTINGS);
@Override
public CharSequence getTitle() {
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 bf4245b..f078b53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -18,10 +18,12 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeAnimator;
import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
@@ -32,6 +34,7 @@
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
+import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
@@ -56,6 +59,8 @@
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.NotificationOverflowContainer;
+import com.android.systemui.statusbar.NotificationSettingsIconRow;
+import com.android.systemui.statusbar.NotificationSettingsIconRow.SettingsIconRowListener;
import com.android.systemui.statusbar.StackScrollerDecorView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -72,7 +77,8 @@
*/
public class NotificationStackScrollLayout extends ViewGroup
implements SwipeHelper.Callback, ExpandHelper.Callback, ScrollAdapter,
- ExpandableView.OnHeightChangedListener, NotificationGroupManager.OnGroupChangeListener {
+ ExpandableView.OnHeightChangedListener, NotificationGroupManager.OnGroupChangeListener,
+ SettingsIconRowListener {
public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
private static final String TAG = "StackScroller";
@@ -207,6 +213,11 @@
*/
private int mMaxScrollAfterExpand;
private SwipeHelper.LongPressListener mLongPressListener;
+ private GearDisplayedListener mGearDisplayedListener;
+
+ private NotificationSettingsIconRow mCurrIconRow;
+ private View mTranslatingParentView;
+ private View mGearExposedView;
/**
* Should in this touch motion only be scrolling allowed? It's true when the scroller was
@@ -304,8 +315,7 @@
minHeight, maxHeight);
mExpandHelper.setEventSource(this);
mExpandHelper.setScrollAdapter(this);
-
- mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, getContext());
+ mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, this, getContext());
mSwipeHelper.setLongPressListener(mLongPressListener);
mStackScrollAlgorithm = new StackScrollAlgorithm(context);
initView(context);
@@ -321,6 +331,13 @@
}
@Override
+ public void onGearTouched(ExpandableNotificationRow row) {
+ if (mLongPressListener != null) {
+ mLongPressListener.onLongPress(row, 0, 0);
+ }
+ }
+
+ @Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom, mBackgroundPaint);
if (DEBUG) {
@@ -630,6 +647,10 @@
mLongPressListener = listener;
}
+ public void setGearDisplayedListener(GearDisplayedListener listener) {
+ mGearDisplayedListener = listener;
+ }
+
public void setQsContainer(ViewGroup qsContainer) {
mQsContainer = qsContainer;
}
@@ -666,7 +687,7 @@
}
@Override
- public void onChildSnappedBack(View animView) {
+ public void onChildSnappedBack(View animView, float targetLeft) {
mAmbientState.onDragFinished(animView);
if (!mDragAnimPendingChildren.contains(animView)) {
if (mAnimationsEnabled) {
@@ -678,6 +699,13 @@
// We start the swipe and snap back in the same frame, we don't want any animation
mDragAnimPendingChildren.remove(animView);
}
+
+ if (targetLeft == 0 && mCurrIconRow != null) {
+ mCurrIconRow.resetState();
+ if (mGearExposedView != null && mGearExposedView == mTranslatingParentView) {
+ mGearExposedView = null;
+ }
+ }
}
@Override
@@ -686,7 +714,7 @@
mScrimController.setTopHeadsUpDragAmount(animView,
Math.min(Math.abs(swipeProgress - 1.0f), 1.0f));
}
- return false;
+ return true; // Don't fade out the notification
}
public void onBeginDrag(View v) {
@@ -726,8 +754,21 @@
return mPhoneStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
}
+ @Override
public View getChildAtPosition(MotionEvent ev) {
- return getChildAtPosition(ev.getX(), ev.getY());
+ View child = getChildAtPosition(ev.getX(), ev.getY());
+ if (child instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+ ExpandableNotificationRow parent = row.getNotificationParent();
+ if (mGearExposedView != null && parent != null
+ && parent.areChildrenExpanded() && mGearExposedView == parent) {
+ // In this case the group is expanded and showing the gear for the
+ // group, further interaction should apply to the group, not any
+ // child notifications so we use the parent of the child.
+ child = row.getNotificationParent();
+ }
+ }
+ return child;
}
public ExpandableView getClosestChildAtRawPosition(float touchX, float touchY) {
@@ -841,10 +882,6 @@
return mScrollingEnabled;
}
- public View getChildContentView(View v) {
- return v;
- }
-
public boolean canChildBeDismissed(View v) {
return StackScrollAlgorithm.canChildBeDismissed(v);
}
@@ -3008,6 +3045,9 @@
disableClipOptimization();
}
handleDismissAllClipping();
+ if (mCurrIconRow != null & mCurrIconRow.isVisible()) {
+ mCurrIconRow.getNotificationParent().animateTranslateNotification(0 /* left target */);
+ }
}
private void handleDismissAllClipping() {
@@ -3268,6 +3308,247 @@
public void flingTopOverscroll(float velocity, boolean open);
}
+ /**
+ * A listener that is notified when the gear is shown behind a notification.
+ */
+ public interface GearDisplayedListener {
+ void onGearDisplayed(ExpandableNotificationRow row);
+ }
+
+ private class NotificationSwipeHelper extends SwipeHelper {
+ private static final int MOVE_STATE_LEFT = -1;
+ private static final int MOVE_STATE_UNDEFINED = 0;
+ private static final int MOVE_STATE_RIGHT = 1;
+
+ private static final long GEAR_SHOW_DELAY = 60;
+
+ private ArrayList<View> mTranslatingViews = new ArrayList<>();
+ private CheckForDrag mCheckForDrag;
+ private Handler mHandler;
+ private int mMoveState = MOVE_STATE_UNDEFINED;
+
+ public NotificationSwipeHelper(int swipeDirection, Callback callback, Context context) {
+ super(swipeDirection, callback, context);
+ mHandler = new Handler();
+ }
+
+ @Override
+ public void onDownUpdate(View currView) {
+ // Set the active view
+ mTranslatingParentView = currView;
+
+ // Reset check for drag gesture
+ mCheckForDrag = null;
+
+ // Slide back any notifications that might be showing a gear
+ resetExposedGearView();
+
+ if (currView instanceof ExpandableNotificationRow) {
+ // Set the listener for the current row's gear
+ mCurrIconRow = ((ExpandableNotificationRow) currView).getSettingsRow();
+ mCurrIconRow.setGearListener(NotificationStackScrollLayout.this);
+
+ // And the translating children
+ mTranslatingViews = ((ExpandableNotificationRow) currView).getContentViews();
+ }
+ mMoveState = MOVE_STATE_UNDEFINED;
+ }
+
+ @Override
+ public void onMoveUpdate(View view, float translation, float delta) {
+ final int newMoveState = (delta < 0) ? MOVE_STATE_RIGHT : MOVE_STATE_LEFT;
+ if (mMoveState != MOVE_STATE_UNDEFINED && mMoveState != newMoveState) {
+ // Changed directions, make sure we check for drag again.
+ mCheckForDrag = null;
+ }
+ mMoveState = newMoveState;
+
+ if (view instanceof ExpandableNotificationRow) {
+ ((ExpandableNotificationRow) view).setTranslationForOutline(translation);
+ if (!isPinnedHeadsUp(view)) {
+ // Only show the gear if we're not a heads up view.
+ checkForDrag();
+ if (mCurrIconRow != null) {
+ mCurrIconRow.updateSettingsIcons(translation, getSize(view));
+ }
+ }
+ }
+ }
+
+ @Override
+ public void dismissChild(final View view, float velocity) {
+ cancelCheckForDrag();
+ super.dismissChild(view, velocity);
+ }
+
+ @Override
+ public void snapChild(final View animView, final float targetLeft, float velocity) {
+ final float snapBackThreshold = getSpaceForGear(animView);
+ final float translation = getTranslation(animView);
+ final boolean fromLeft = translation > 0;
+ final float absTrans = Math.abs(translation);
+ final float notiThreshold = getSize(mTranslatingParentView) * 0.4f;
+
+ boolean pastGear = (fromLeft && translation >= snapBackThreshold * 0.4f
+ && translation <= notiThreshold) ||
+ (!fromLeft && absTrans >= snapBackThreshold * 0.4f
+ && absTrans <= notiThreshold);
+
+ if (pastGear && !isPinnedHeadsUp(animView)) {
+ // bouncity
+ final float target = fromLeft ? snapBackThreshold : -snapBackThreshold;
+ mGearExposedView = mTranslatingParentView;
+ if (mGearDisplayedListener != null
+ && (animView instanceof ExpandableNotificationRow)) {
+ mGearDisplayedListener.onGearDisplayed((ExpandableNotificationRow) animView);
+ }
+ super.snapChild(animView, target, velocity);
+ } else {
+ super.snapChild(animView, 0, velocity);
+ }
+ }
+
+ @Override
+ public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) {
+ if (mDismissAllInProgress) {
+ // When dismissing all, we translate the entire view instead.
+ super.onTranslationUpdate(animView, value, canBeDismissed);
+ return;
+ }
+ if (animView instanceof ExpandableNotificationRow) {
+ ((ExpandableNotificationRow) animView).setTranslationForOutline(value);
+ }
+ if (mCurrIconRow != null) {
+ mCurrIconRow.updateSettingsIcons(value, getSize(animView));
+ }
+ }
+
+ @Override
+ public Animator getViewTranslationAnimator(View v, float target,
+ AnimatorUpdateListener listener) {
+ if (mDismissAllInProgress) {
+ // When dismissing all, we translate the entire view instead.
+ return super.getViewTranslationAnimator(v, target, listener);
+ }
+ ArrayList<Animator> animators = new ArrayList<Animator>();
+ for (int i = 0; i < mTranslatingViews.size(); i++) {
+ ObjectAnimator anim = createTranslationAnimation(mTranslatingViews.get(i), target);
+ animators.add(anim);
+ if (i == 0 && listener != null) {
+ anim.addUpdateListener(listener);
+ }
+ }
+ AnimatorSet set = new AnimatorSet();
+ set.playTogether(animators);
+ return set;
+ }
+
+ @Override
+ public void setTranslation(View v, float translate) {
+ if (mDismissAllInProgress) {
+ // When dismissing all, we translate the entire view instead.
+ super.setTranslation(v, translate);
+ return;
+ }
+ // Translate the group of views
+ for (int i = 0; i < mTranslatingViews.size(); i++) {
+ if (mTranslatingViews.get(i) != null) {
+ super.setTranslation(mTranslatingViews.get(i), translate);
+ }
+ }
+ }
+
+ @Override
+ public float getTranslation(View v) {
+ if (mDismissAllInProgress) {
+ // When dismissing all, we translate the entire view instead.
+ return super.getTranslation(v);
+ }
+ // All of the views in the list should have same translation, just use first one.
+ if (mTranslatingViews.size() > 0) {
+ return super.getTranslation(mTranslatingViews.get(0));
+ }
+ return 0;
+ }
+
+
+ /**
+ * Returns the horizontal space in pixels required to display the gear behind a
+ * notification.
+ */
+ private float getSpaceForGear(View view) {
+ if (view instanceof ExpandableNotificationRow) {
+ return ((ExpandableNotificationRow) view).getSpaceForGear();
+ }
+ return 0;
+ }
+
+ private void checkForDrag() {
+ if (mCheckForDrag == null) {
+ mCheckForDrag = new CheckForDrag();
+ mHandler.postDelayed(mCheckForDrag, GEAR_SHOW_DELAY);
+ }
+ }
+
+ private void cancelCheckForDrag() {
+ if (mCurrIconRow != null) {
+ mCurrIconRow.cancelFadeAnimator();
+ }
+ mHandler.removeCallbacks(mCheckForDrag);
+ mCheckForDrag = null;
+ }
+
+ private final class CheckForDrag implements Runnable {
+ @Override
+ public void run() {
+ final float translation = getTranslation(mTranslatingParentView);
+ final float absTransX = Math.abs(translation);
+ final float bounceBackToGearWidth = getSpaceForGear(mTranslatingParentView);
+ final float notiThreshold = getSize(mTranslatingParentView) * 0.4f;
+ if (mCurrIconRow != null && absTransX >= bounceBackToGearWidth * 0.4
+ && absTransX < notiThreshold) {
+ // Show icon
+ mCurrIconRow.fadeInSettings(translation > 0 /* fromLeft */, translation,
+ notiThreshold);
+ } else {
+ // Allow more to be posted if this wasn't a drag.
+ mCheckForDrag = null;
+ }
+ }
+ }
+
+ private void resetExposedGearView() {
+ if (mGearExposedView == null || mGearExposedView == mTranslatingParentView) {
+ // If no gear is showing or it's showing for this view we do nothing.
+ return;
+ }
+
+ final View prevGearExposedView = mGearExposedView;
+ mGearExposedView = null;
+
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animator) {
+ if (prevGearExposedView instanceof ExpandableNotificationRow) {
+ ((ExpandableNotificationRow) prevGearExposedView).getSettingsRow()
+ .resetState();
+ }
+ }
+ };
+ AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ if (prevGearExposedView instanceof ExpandableNotificationRow) {
+ ((ExpandableNotificationRow) prevGearExposedView)
+ .setTranslationForOutline((float) animation.getAnimatedValue());
+ }
+ }
+ };
+ Animator set = getViewTranslationAnimator(prevGearExposedView, 0, updateListener);
+ set.addListener(listener);
+ set.start();
+ }
+ }
+
static class AnimationEvent {
static AnimationFilter[] FILTERS = new AnimationFilter[] {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NightModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/NightModeFragment.java
index 1377407..e9650ea 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NightModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NightModeFragment.java
@@ -42,6 +42,9 @@
Listener, OnPreferenceChangeListener {
private static final String TAG = "NightModeFragment";
+
+ public static final String EXTRA_SHOW_NIGHT_MODE = "show_night_mode";
+
private static final CharSequence KEY_AUTO = "auto";
private static final CharSequence KEY_DARK_THEME = "dark_theme";
private static final CharSequence KEY_ADJUST_TINT = "adjust_tint";
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java b/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
index 1311f30..61135bd 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
@@ -16,6 +16,7 @@
package com.android.systemui.tuner;
import android.app.ActivityManager;
+import android.content.Intent;
import android.provider.Settings;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -60,6 +61,12 @@
}
@Override
+ public Intent getLongClickIntent() {
+ return new Intent(mContext, TunerActivity.class)
+ .putExtra(NightModeFragment.EXTRA_SHOW_NIGHT_MODE, true);
+ }
+
+ @Override
protected void handleClick() {
mNightModeController.setNightMode(!mNightModeController.isEnabled());
refreshState();
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 4225b48..def597d 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -36,7 +36,10 @@
super.onCreate(savedInstanceState);
if (getFragmentManager().findFragmentByTag(TAG_TUNER) == null) {
- getFragmentManager().beginTransaction().replace(R.id.content_frame, new TunerFragment(),
+ boolean showNightMode = getIntent().getBooleanExtra(
+ NightModeFragment.EXTRA_SHOW_NIGHT_MODE, false);
+ getFragmentManager().beginTransaction().replace(R.id.content_frame,
+ showNightMode ? new NightModeFragment() : new TunerFragment(),
TAG_TUNER).commit();
}
}
diff --git a/services/core/java/com/android/server/notification/TopicImportanceExtractor.java b/services/core/java/com/android/server/notification/ImportanceExtractor.java
similarity index 84%
rename from services/core/java/com/android/server/notification/TopicImportanceExtractor.java
rename to services/core/java/com/android/server/notification/ImportanceExtractor.java
index c6b3e0f..885b9b7 100644
--- a/services/core/java/com/android/server/notification/TopicImportanceExtractor.java
+++ b/services/core/java/com/android/server/notification/ImportanceExtractor.java
@@ -21,7 +21,7 @@
/**
* Determines the importance of the given notification.
*/
-public class TopicImportanceExtractor implements NotificationSignalExtractor {
+public class ImportanceExtractor implements NotificationSignalExtractor {
private static final String TAG = "ImportantTopicExtractor";
private static final boolean DBG = false;
@@ -42,9 +42,8 @@
return null;
}
- final int topicImportance = mConfig.getImportance(record.sbn.getPackageName(),
- record.sbn.getUid(), record.sbn.getNotification().getTopic());
- record.setTopicImportance(topicImportance);
+ record.setUserImportance(
+ mConfig.getImportance(record.sbn.getPackageName(), record.sbn.getUid()));
return null;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ede1a2f..95198a3 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -30,7 +30,6 @@
import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_CHANGED;
import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_SUSPENDED;
import static android.service.notification.NotificationAssistantService.REASON_PROFILE_TURNED_OFF;
-import static android.service.notification.NotificationAssistantService.REASON_TOPIC_BANNED;
import static android.service.notification.NotificationAssistantService.REASON_USER_STOPPED;
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF;
@@ -754,7 +753,7 @@
for (String pkgName : pkgList) {
if (cancelNotifications) {
cancelAllNotificationsInt(MY_UID, MY_PID, pkgName, 0, 0, !queryRestart,
- changeUserId, reason, null, null);
+ changeUserId, reason, null);
}
}
}
@@ -787,14 +786,14 @@
int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
if (userHandle >= 0) {
cancelAllNotificationsInt(MY_UID, MY_PID, null, 0, 0, true, userHandle,
- REASON_USER_STOPPED, null, null);
+ REASON_USER_STOPPED, null);
}
} else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED)) {
boolean inQuietMode = intent.getBooleanExtra(Intent.EXTRA_QUIET_MODE, false);
int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
if (inQuietMode && userHandle >= 0) {
cancelAllNotificationsInt(MY_UID, MY_PID, null, 0, 0, true, userHandle,
- REASON_PROFILE_TURNED_OFF, null, null);
+ REASON_PROFILE_TURNED_OFF, null);
}
} else if (action.equals(Intent.ACTION_USER_PRESENT)) {
// turn off LED when user passes through lock screen
@@ -1086,7 +1085,7 @@
// Now, cancel any outstanding notifications that are part of a just-disabled app
if (ENABLE_BLOCKED_NOTIFICATIONS && !enabled) {
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true, UserHandle.getUserId(uid),
- REASON_PACKAGE_BANNED, null, null);
+ REASON_PACKAGE_BANNED, null);
}
}
@@ -1250,7 +1249,7 @@
// running foreground services.
cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId,
- REASON_APP_CANCEL_ALL, null, null);
+ REASON_APP_CANCEL_ALL, null);
}
@Override
@@ -1279,79 +1278,50 @@
}
@Override
- public boolean hasBannedTopics(String pkg, int uid) {
+ public void setPriority(String pkg, int uid, int priority) {
checkCallerIsSystem();
- return mRankingHelper.hasBannedTopics(pkg, uid);
- }
-
- @Override
- public ParceledListSlice<Notification.Topic> getTopics(String pkg, int uid) {
- checkCallerIsSystem();
- return new ParceledListSlice<Notification.Topic>(mRankingHelper.getTopics(pkg, uid));
- }
-
- @Override
- public void setPriority(String pkg, int uid, Notification.Topic topic, int priority) {
- checkCallerIsSystem();
- mRankingHelper.setPriority(pkg, uid, topic, priority);
+ mRankingHelper.setPriority(pkg, uid, priority);
savePolicyFile();
}
@Override
- public int getPriority(String pkg, int uid, Notification.Topic topic) {
+ public int getPriority(String pkg, int uid) {
checkCallerIsSystem();
- return mRankingHelper.getPriority(pkg, uid, topic);
+ return mRankingHelper.getPriority(pkg, uid);
}
@Override
- public void setVisibilityOverride(String pkg, int uid, Notification.Topic topic,
- int visibility) {
+ public void setVisibilityOverride(String pkg, int uid, int visibility) {
checkCallerIsSystem();
- mRankingHelper.setVisibilityOverride(pkg, uid, topic, visibility);
+ mRankingHelper.setVisibilityOverride(pkg, uid, visibility);
savePolicyFile();
}
@Override
- public int getVisibilityOverride(String pkg, int uid, Notification.Topic topic) {
+ public int getVisibilityOverride(String pkg, int uid) {
checkCallerIsSystem();
- return mRankingHelper.getVisibilityOverride(pkg, uid, topic);
+ return mRankingHelper.getVisibilityOverride(pkg, uid);
}
@Override
- public void setImportance(String pkg, int uid, Notification.Topic topic,
- int importance) {
+ public void setImportance(String pkg, int uid, int importance) {
enforceSystemOrSystemUI("Caller not system or systemui");
- if (topic == null) {
- // App wide, potentially store block in app ops.
- setNotificationsEnabledForPackageImpl(pkg, uid,
- importance != NotificationListenerService.Ranking.IMPORTANCE_NONE);
- } else {
- if (NotificationListenerService.Ranking.IMPORTANCE_NONE == importance) {
- cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true,
- UserHandle.getUserId(uid),
- REASON_TOPIC_BANNED, topic, null);
- }
- }
- mRankingHelper.setImportance(pkg, uid, topic, importance);
+ setNotificationsEnabledForPackageImpl(pkg, uid,
+ importance != NotificationListenerService.Ranking.IMPORTANCE_NONE);
+ mRankingHelper.setImportance(pkg, uid, importance);
savePolicyFile();
}
@Override
- public int getTopicImportance(String pkg, String topicId) {
+ public int getPackageImportance(String pkg) {
checkCallerIsSystemOrSameApp(pkg);
- return mRankingHelper.getImportance(pkg, Binder.getCallingUid(), topicId);
+ return mRankingHelper.getImportance(pkg, Binder.getCallingUid());
}
@Override
- public int getImportance(String pkg, int uid, Notification.Topic topic) {
+ public int getImportance(String pkg, int uid) {
checkCallerIsSystem();
- return mRankingHelper.getImportance(pkg, uid, topic);
- }
-
- @Override
- public boolean doesUserUseTopics(String pkg, int uid) {
- enforceSystemOrSystemUI("Caller not system or systemui");
- return mRankingHelper.doesUserUseTopics(pkg, uid);
+ return mRankingHelper.getImportance(pkg, uid);
}
/**
@@ -2381,11 +2351,9 @@
mRankingHelper.extractSignals(r);
- // why is this here?
- savePolicyFile();
final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
- // blocked apps/topics
+ // blocked apps
if (r.getImportance() == NotificationListenerService.Ranking.IMPORTANCE_NONE
|| !noteNotificationOp(pkg, callingUid) || isPackageSuspended) {
if (!isSystemNotification) {
@@ -3182,11 +3150,11 @@
}
/**
- * Cancels all notifications from a given package or topic that have all of the
+ * Cancels all notifications from a given package that have all of the
* {@code mustHaveFlags}.
*/
boolean cancelAllNotificationsInt(int callingUid, int callingPid, String pkg, int mustHaveFlags,
- int mustNotHaveFlags, boolean doit, int userId, int reason, Notification.Topic topic,
+ int mustNotHaveFlags, boolean doit, int userId, int reason,
ManagedServiceInfo listener) {
String listenerName = listener == null ? null : listener.component.toShortString();
EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
@@ -3214,10 +3182,6 @@
if (pkg != null && !r.sbn.getPackageName().equals(pkg)) {
continue;
}
- if (topic != null
- && !topic.getId().equals(r.getNotification().getTopic().getId())) {
- continue;
- }
if (canceledNotifications == null) {
canceledNotifications = new ArrayList<>();
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 2ca5534..25d17f6 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -35,7 +35,6 @@
import android.service.notification.StatusBarNotification;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
import com.android.server.EventLogTags;
import java.io.PrintWriter;
@@ -92,12 +91,12 @@
private int mAuthoritativeRank;
private String mGlobalSortKey;
private int mPackageVisibility;
- private int mTopicImportance = IMPORTANCE_UNSPECIFIED;
+ private int mUserImportance = IMPORTANCE_UNSPECIFIED;
private int mImportance = IMPORTANCE_UNSPECIFIED;
private CharSequence mImportanceExplanation = null;
private int mSuppressedVisualEffects = 0;
- private String mTopicExplanation;
+ private String mUserExplanation;
private String mPeopleExplanation;
@VisibleForTesting
@@ -183,7 +182,7 @@
mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
mCreationTimeMs = previous.mCreationTimeMs;
mVisibleSinceMs = previous.mVisibleSinceMs;
- mTopicImportance = previous.mTopicImportance;
+ mUserImportance = previous.mUserImportance;
mImportance = previous.mImportance;
mImportanceExplanation = previous.mImportanceExplanation;
// Don't copy mGlobalSortKey, recompute it.
@@ -275,8 +274,8 @@
pw.println(prefix + " mRecentlyIntrusive=" + mRecentlyIntrusive);
pw.println(prefix + " mPackagePriority=" + mPackagePriority);
pw.println(prefix + " mPackageVisibility=" + mPackageVisibility);
- pw.println(prefix + " mTopicImportance="
- + NotificationListenerService.Ranking.importanceToString(mTopicImportance));
+ pw.println(prefix + " mUserImportance="
+ + NotificationListenerService.Ranking.importanceToString(mUserImportance));
pw.println(prefix + " mImportance="
+ NotificationListenerService.Ranking.importanceToString(mImportance));
pw.println(prefix + " mImportanceExplanation=" + mImportanceExplanation);
@@ -357,17 +356,17 @@
return mPackageVisibility;
}
- public void setTopicImportance(int importance) {
- mTopicImportance = importance;
- applyTopicImportance();
+ public void setUserImportance(int importance) {
+ mUserImportance = importance;
+ applyUserImportance();
}
- private String getTopicExplanation() {
- if (mTopicExplanation == null) {
- mTopicExplanation =
- mContext.getString(com.android.internal.R.string.importance_from_topic);
+ private String getUserExplanation() {
+ if (mUserExplanation == null) {
+ mUserExplanation =
+ mContext.getString(com.android.internal.R.string.importance_from_user);
}
- return mTopicExplanation;
+ return mUserExplanation;
}
private String getPeopleExplanation() {
@@ -378,15 +377,15 @@
return mPeopleExplanation;
}
- private void applyTopicImportance() {
- if (mTopicImportance != NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED) {
- mImportance = mTopicImportance;
- mImportanceExplanation = getTopicExplanation();
+ private void applyUserImportance() {
+ if (mUserImportance != NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED) {
+ mImportance = mUserImportance;
+ mImportanceExplanation = getUserExplanation();
}
}
- public int getTopicImportance() {
- return mTopicImportance;
+ public int getUserImportance() {
+ return mUserImportance;
}
public void setImportance(int importance, CharSequence explanation) {
@@ -394,7 +393,7 @@
mImportance = importance;
mImportanceExplanation = explanation;
}
- applyTopicImportance();
+ applyUserImportance();
}
public int getImportance() {
@@ -529,6 +528,6 @@
}
public boolean isImportanceFromUser() {
- return mImportance == mTopicImportance;
+ return mImportance == mUserImportance;
}
}
diff --git a/services/core/java/com/android/server/notification/TopicPriorityExtractor.java b/services/core/java/com/android/server/notification/PriorityExtractor.java
similarity index 84%
rename from services/core/java/com/android/server/notification/TopicPriorityExtractor.java
rename to services/core/java/com/android/server/notification/PriorityExtractor.java
index 1df5c2b..6c76476 100644
--- a/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
+++ b/services/core/java/com/android/server/notification/PriorityExtractor.java
@@ -21,7 +21,7 @@
/**
* Determines if the given notification can bypass Do Not Disturb.
*/
-public class TopicPriorityExtractor implements NotificationSignalExtractor {
+public class PriorityExtractor implements NotificationSignalExtractor {
private static final String TAG = "ImportantTopicExtractor";
private static final boolean DBG = false;
@@ -42,9 +42,8 @@
return null;
}
- final int packagePriority = mConfig.getPriority(record.sbn.getPackageName(),
- record.sbn.getUid(), record.sbn.getNotification().getTopic());
- record.setPackagePriority(packagePriority);
+ record.setPackagePriority(
+ mConfig.getPriority(record.sbn.getPackageName(), record.sbn.getUid()));
return null;
}
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 9773474..b5cc2ef 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -15,30 +15,17 @@
*/
package com.android.server.notification;
-import android.app.Notification;
-
-import java.util.List;
-
public interface RankingConfig {
- List<Notification.Topic> getTopics(String packageName, int uid);
+ int getPriority(String packageName, int uid);
- int getPriority(String packageName, int uid, Notification.Topic topic);
+ void setPriority(String packageName, int uid, int priority);
- void setPriority(String packageName, int uid, Notification.Topic topic, int priority);
+ int getVisibilityOverride(String packageName, int uid);
- int getVisibilityOverride(String packageName, int uid, Notification.Topic topic);
+ void setVisibilityOverride(String packageName, int uid, int visibility);
- void setVisibilityOverride(String packageName, int uid, Notification.Topic topic,
- int visibility);
+ void setImportance(String packageName, int uid, int importance);
- void setImportance(String packageName, int uid, Notification.Topic topic, int importance);
-
- int getImportance(String packageName, int uid, Notification.Topic topic);
-
- boolean doesUserUseTopics(String packageName, int uid);
-
- boolean hasBannedTopics(String packageName, int uid);
-
- int getImportance(String packageName, int uid, String topicId);
+ int getImportance(String packageName, int uid);
}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 91eab10..fd96a78 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -20,14 +20,11 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.UserHandle;
-import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Slog;
-import com.android.internal.R;
-
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -36,8 +33,6 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
-import java.util.Map;
public class RankingHelper implements RankingConfig {
private static final String TAG = "RankingHelper";
@@ -47,7 +42,6 @@
private static final String TAG_RANKING = "ranking";
private static final String TAG_PACKAGE = "package";
private static final String ATT_VERSION = "version";
- private static final String TAG_TOPIC = "topic";
private static final String ATT_NAME = "name";
private static final String ATT_UID = "uid";
@@ -141,8 +135,6 @@
if (type == XmlPullParser.START_TAG) {
if (TAG_PACKAGE.equals(tag)) {
int uid = safeInt(parser, ATT_UID, Record.UNKNOWN_UID);
- int priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
- int vis = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
String name = parser.getAttributeValue(null, ATT_NAME);
if (!TextUtils.isEmpty(name)) {
@@ -165,16 +157,8 @@
r = getOrCreateRecord(name, uid);
}
r.importance = safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
- r.priority = priority;
- r.visibility = vis;
-
- // Migrate package level settings to the default topic.
- // Might be overwritten by parseTopics.
- Topic defaultTopic = r.topics.get(Notification.TOPIC_DEFAULT);
- defaultTopic.priority = priority;
- defaultTopic.visibility = vis;
-
- parseTopics(r, parser);
+ r.priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
+ r.visibility = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
}
}
}
@@ -182,42 +166,6 @@
throw new IllegalStateException("Failed to reach END_DOCUMENT");
}
- public void parseTopics(Record r, XmlPullParser parser)
- throws XmlPullParserException, IOException {
- final int innerDepth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
-
- String tagName = parser.getName();
- if (TAG_TOPIC.equals(tagName)) {
- int priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
- int vis = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
- int importance = safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
- String id = parser.getAttributeValue(null, ATT_TOPIC_ID);
- CharSequence label = parser.getAttributeValue(null, ATT_TOPIC_LABEL);
-
- if (!TextUtils.isEmpty(id)) {
- Topic topic = new Topic(new Notification.Topic(id, label));
-
- if (priority != DEFAULT_PRIORITY) {
- topic.priority = priority;
- }
- if (vis != DEFAULT_VISIBILITY) {
- topic.visibility = vis;
- }
- if (importance != DEFAULT_IMPORTANCE) {
- topic.importance = importance;
- }
- r.topics.put(id, topic);
- }
- }
- }
- }
-
private static String recordKey(String pkg, int uid) {
return pkg + "|" + uid;
}
@@ -229,7 +177,6 @@
r = new Record();
r.pkg = pkg;
r.uid = uid;
- r.topics.put(Notification.TOPIC_DEFAULT, new Topic(createDefaultTopic()));
mRecords.put(key, r);
}
return r;
@@ -246,46 +193,31 @@
if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_SYSTEM) {
continue;
}
- out.startTag(null, TAG_PACKAGE);
- out.attribute(null, ATT_NAME, r.pkg);
- if (r.importance != DEFAULT_IMPORTANCE) {
- out.attribute(null, ATT_IMPORTANCE, Integer.toString(r.importance));
- }
- if (r.priority != DEFAULT_PRIORITY) {
- out.attribute(null, ATT_PRIORITY, Integer.toString(r.priority));
- }
- if (r.visibility != DEFAULT_VISIBILITY) {
- out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
- }
+ final boolean hasNonDefaultSettings = r.importance != DEFAULT_IMPORTANCE
+ || r.priority != DEFAULT_PRIORITY || r.visibility != DEFAULT_VISIBILITY;
+ if (hasNonDefaultSettings) {
+ out.startTag(null, TAG_PACKAGE);
+ out.attribute(null, ATT_NAME, r.pkg);
+ if (r.importance != DEFAULT_IMPORTANCE) {
+ out.attribute(null, ATT_IMPORTANCE, Integer.toString(r.importance));
+ }
+ if (r.priority != DEFAULT_PRIORITY) {
+ out.attribute(null, ATT_PRIORITY, Integer.toString(r.priority));
+ }
+ if (r.visibility != DEFAULT_VISIBILITY) {
+ out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
+ }
- if (!forBackup) {
- out.attribute(null, ATT_UID, Integer.toString(r.uid));
- }
+ if (!forBackup) {
+ out.attribute(null, ATT_UID, Integer.toString(r.uid));
+ }
- writeTopicsXml(out, r);
- out.endTag(null, TAG_PACKAGE);
+ out.endTag(null, TAG_PACKAGE);
+ }
}
out.endTag(null, TAG_RANKING);
}
- public void writeTopicsXml(XmlSerializer out, Record r) throws IOException {
- for (Topic t : r.topics.values()) {
- out.startTag(null, TAG_TOPIC);
- out.attribute(null, ATT_TOPIC_ID, t.topic.getId());
- out.attribute(null, ATT_TOPIC_LABEL, t.topic.getLabel().toString());
- if (t.priority != DEFAULT_PRIORITY) {
- out.attribute(null, ATT_PRIORITY, Integer.toString(t.priority));
- }
- if (t.visibility != DEFAULT_VISIBILITY) {
- out.attribute(null, ATT_VISIBILITY, Integer.toString(t.visibility));
- }
- if (t.importance != DEFAULT_IMPORTANCE) {
- out.attribute(null, ATT_IMPORTANCE, Integer.toString(t.importance));
- }
- out.endTag(null, TAG_TOPIC);
- }
- }
-
private void updateConfig() {
final int N = mSignalExtractors.length;
for (int i = 0; i < N; i++) {
@@ -370,189 +302,62 @@
}
}
- private static boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
- final String val = parser.getAttributeValue(null, att);
- return tryParseBool(val, defValue);
- }
-
private static boolean tryParseBool(String value, boolean defValue) {
if (TextUtils.isEmpty(value)) return defValue;
return Boolean.valueOf(value);
}
+ /**
+ * Gets priority.
+ */
@Override
- public List<Notification.Topic> getTopics(String packageName, int uid) {
- final Record r = getOrCreateRecord(packageName, uid);
- List<Notification.Topic> topics = new ArrayList<>();
- for (Topic t : r.topics.values()) {
- topics.add(t.topic);
- }
- return topics;
- }
-
- @Override
- public boolean hasBannedTopics(String packageName, int uid) {
- final Record r = getOrCreateRecord(packageName, uid);
- for (Topic t : r.topics.values()) {
- if (t.importance == Ranking.IMPORTANCE_NONE) {
- return true;
- }
- }
- return false;
+ public int getPriority(String packageName, int uid) {
+ return getOrCreateRecord(packageName, uid).priority;
}
/**
- * Gets priority. If a topic is given, returns the priority of that topic. Otherwise, the
- * priority of the app.
+ * Sets priority.
*/
@Override
- public int getPriority(String packageName, int uid, Notification.Topic topic) {
- final Record r = getOrCreateRecord(packageName, uid);
- if (topic == null) {
- return r.priority;
- }
- return getOrCreateTopic(r, topic).priority;
- }
-
- /**
- * Sets priority. If a topic is given, sets the priority of that topic. If not,
- * sets the default priority for all new topics that appear in the future, and resets
- * the priority of all current topics.
- */
- @Override
- public void setPriority(String packageName, int uid, Notification.Topic topic,
- int priority) {
- final Record r = getOrCreateRecord(packageName, uid);
- if (topic == null) {
- r.priority = priority;
- for (Topic t : r.topics.values()) {
- t.priority = priority;
- }
- } else {
- getOrCreateTopic(r, topic).priority = priority;
- }
+ public void setPriority(String packageName, int uid, int priority) {
+ getOrCreateRecord(packageName, uid).priority = priority;
updateConfig();
}
/**
- * Gets visual override. If a topic is given, returns the override of that topic. Otherwise, the
- * override of the app.
+ * Gets visual override.
*/
@Override
- public int getVisibilityOverride(String packageName, int uid, Notification.Topic topic) {
- final Record r = getOrCreateRecord(packageName, uid);
- if (topic == null) {
- return r.visibility;
- }
- return getOrCreateTopic(r, topic).visibility;
+ public int getVisibilityOverride(String packageName, int uid) {
+ return getOrCreateRecord(packageName, uid).visibility;
}
/**
- * Sets visibility override. If a topic is given, sets the override of that topic. If not,
- * sets the default override for all new topics that appear in the future, and resets
- * the override of all current topics.
+ * Sets visibility override.
*/
@Override
- public void setVisibilityOverride(String pkgName, int uid, Notification.Topic topic,
- int visibility) {
- final Record r = getOrCreateRecord(pkgName, uid);
- if (topic == null) {
- r.visibility = visibility;
- for (Topic t : r.topics.values()) {
- t.visibility = visibility;
- }
- } else {
- getOrCreateTopic(r, topic).visibility = visibility;
- }
+ public void setVisibilityOverride(String pkgName, int uid, int visibility) {
+ getOrCreateRecord(pkgName, uid).visibility = visibility;
updateConfig();
}
/**
- * Gets the importance of a topic. Unlike {@link #getImportance(String, int, String)}, does not
- * create package or topic records if they don't exist.
+ * Gets importance.
*/
@Override
- public int getImportance(String packageName, int uid, String topicId) {
- final String key = recordKey(packageName, uid);
- Record r = mRecords.get(key);
- if (r == null) {
- return Ranking.IMPORTANCE_UNSPECIFIED;
- }
- Topic t = r.topics.get(topicId);
- if (t == null) {
- return Ranking.IMPORTANCE_UNSPECIFIED;
- }
- return t.importance;
+ public int getImportance(String packageName, int uid) {
+ return getOrCreateRecord(packageName, uid).importance;
}
/**
- * Gets importance. If a topic is given, returns the importance of that topic. Otherwise, the
- * importance of the app.
+ * Sets importance.
*/
@Override
- public int getImportance(String packageName, int uid, Notification.Topic topic) {
- final Record r = getOrCreateRecord(packageName, uid);
- if (topic == null) {
- return r.importance;
- }
- return getOrCreateTopic(r, topic).importance;
- }
-
- /**
- * Sets importance. If a topic is given, sets the importance of that topic. If not, sets the
- * default importance for all new topics that appear in the future, and resets
- * the importance of all current topics (unless the app is being blocked).
- */
- @Override
- public void setImportance(String pkgName, int uid, Notification.Topic topic,
- int importance) {
- final Record r = getOrCreateRecord(pkgName, uid);
- if (topic == null) {
- r.importance = importance;
- if (Ranking.IMPORTANCE_NONE != importance) {
- for (Topic t : r.topics.values()) {
- t.importance = importance;
- }
- }
- } else {
- getOrCreateTopic(r, topic).importance = importance;
- }
+ public void setImportance(String pkgName, int uid, int importance) {
+ getOrCreateRecord(pkgName, uid).importance = importance;
updateConfig();
}
- @Override
- public boolean doesUserUseTopics(String pkgName, int uid) {
- final Record r = getOrCreateRecord(pkgName, uid);
- for (Topic topic : r.topics.values()) {
- if (topic.importance != Ranking.IMPORTANCE_UNSPECIFIED
- && r.importance != topic.importance)
- return true;
- }
- return false;
- }
-
- private Topic getOrCreateTopic(Record r, Notification.Topic topic) {
- if (topic == null) {
- topic = createDefaultTopic();
- }
- Topic t = r.topics.get(topic.getId());
- if (t != null) {
- return t;
- } else {
- t = new Topic(topic);
- t.importance = r.importance;
- t.priority = r.priority;
- t.visibility = r.visibility;
- r.topics.put(topic.getId(), t);
- return t;
- }
- }
-
- private Notification.Topic createDefaultTopic() {
- return new Notification.Topic(Notification.TOPIC_DEFAULT,
- mContext.getString(R.string.default_notification_topic_label));
- }
-
public void dump(PrintWriter pw, String prefix, NotificationManagerService.DumpFilter filter) {
if (filter == null) {
final int N = mSignalExtractors.length;
@@ -600,25 +405,6 @@
pw.print(Ranking.importanceToString(r.visibility));
}
pw.println();
- for (Topic t : r.topics.values()) {
- pw.print(prefix);
- pw.print(" ");
- pw.print(" ");
- pw.print(t.topic.getId());
- if (t.priority != DEFAULT_PRIORITY) {
- pw.print(" priority=");
- pw.print(Notification.priorityToString(t.priority));
- }
- if (t.visibility != DEFAULT_VISIBILITY) {
- pw.print(" visibility=");
- pw.print(Notification.visibilityToString(t.visibility));
- }
- if (t.importance != DEFAULT_IMPORTANCE) {
- pw.print(" importance=");
- pw.print(Ranking.importanceToString(t.importance));
- }
- pw.println();
- }
}
}
}
@@ -657,17 +443,5 @@
int importance = DEFAULT_IMPORTANCE;
int priority = DEFAULT_PRIORITY;
int visibility = DEFAULT_VISIBILITY;
- Map<String, Topic> topics = new ArrayMap<>();
}
-
- private static class Topic {
- Notification.Topic topic;
- int priority = DEFAULT_PRIORITY;
- int visibility = DEFAULT_VISIBILITY;
- int importance = DEFAULT_IMPORTANCE;
-
- public Topic(Notification.Topic topic) {
- this.topic = topic;
- }
- }
}
diff --git a/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java b/services/core/java/com/android/server/notification/VisibilityExtractor.java
similarity index 79%
rename from services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
rename to services/core/java/com/android/server/notification/VisibilityExtractor.java
index eaa3ed3..2da2b2f 100644
--- a/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
+++ b/services/core/java/com/android/server/notification/VisibilityExtractor.java
@@ -21,8 +21,8 @@
/**
* Determines if the given notification can display sensitive content on the lockscreen.
*/
-public class TopicVisibilityExtractor implements NotificationSignalExtractor {
- private static final String TAG = "TopicVisibilityExtractor";
+public class VisibilityExtractor implements NotificationSignalExtractor {
+ private static final String TAG = "VisibilityExtractor";
private static final boolean DBG = false;
private RankingConfig mConfig;
@@ -42,10 +42,8 @@
return null;
}
- final int packageVisibility = mConfig.getVisibilityOverride(
- record.sbn.getPackageName(), record.sbn.getUid(),
- record.sbn.getNotification().getTopic());
- record.setPackageVisibilityOverride(packageVisibility);
+ record.setPackageVisibilityOverride(
+ mConfig.getVisibilityOverride(record.sbn.getPackageName(), record.sbn.getUid()));
return null;
}
diff --git a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
index 31182fc..f1fe346 100644
--- a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -25,7 +25,6 @@
import org.mockito.MockitoAnnotations;
import android.app.Notification;
-import android.os.Handler;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.test.AndroidTestCase;
@@ -55,14 +54,13 @@
UserHandle user = UserHandle.ALL;
mHelper = new RankingHelper(getContext(), handler, mUsageStats,
- new String[] {TopicImportanceExtractor.class.getName()});
+ new String[] {ImportanceExtractor.class.getName()});
mNotiGroupGSortA = new Notification.Builder(getContext())
.setContentTitle("A")
.setGroup("G")
.setSortKey("A")
.setWhen(1205)
- .setTopic(new Notification.Topic("A", "a"))
.build();
mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", 1, null, 0, 0, 0, mNotiGroupGSortA, user));
@@ -72,7 +70,6 @@
.setGroup("G")
.setSortKey("B")
.setWhen(1200)
- .setTopic(new Notification.Topic("A", "a"))
.build();
mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", 1, null, 0, 0, 0, mNotiGroupGSortB, user));
@@ -80,7 +77,6 @@
mNotiNoGroup = new Notification.Builder(getContext())
.setContentTitle("C")
.setWhen(1201)
- .setTopic(new Notification.Topic("C", "c"))
.build();
mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", 1, null, 0, 0, 0, mNotiNoGroup, user));
@@ -88,7 +84,6 @@
mNotiNoGroup2 = new Notification.Builder(getContext())
.setContentTitle("D")
.setWhen(1202)
- .setTopic(new Notification.Topic("D", "d"))
.build();
mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", 1, null, 0, 0, 0, mNotiNoGroup2, user));
@@ -97,7 +92,6 @@
.setContentTitle("E")
.setWhen(1201)
.setSortKey("A")
- .setTopic(new Notification.Topic("E", "e"))
.build();
mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", 1, null, 0, 0, 0, mNotiNoGroupSortA, user));
@@ -152,26 +146,4 @@
ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
mHelper.sort(notificationList);
}
-
- @SmallTest
- public void testTopicImportanceExtractor() throws Exception {
- mHelper.setImportance("package", 0, new Notification.Topic("A", "a"), IMPORTANCE_MAX);
- // There is no B. There never was a b. Moving on...
- mHelper.setImportance("package", 0, new Notification.Topic("C", "c"), IMPORTANCE_HIGH);
- mHelper.setImportance("package", 0, new Notification.Topic("D", "d"), IMPORTANCE_LOW);
- // watch out: different package.
- mHelper.setImportance("package2", 0, new Notification.Topic("E", "e"), IMPORTANCE_NONE);
-
- TopicImportanceExtractor validator = mHelper.findExtractor(TopicImportanceExtractor.class);
- validator.process(mRecordGroupGSortA);
- validator.process(mRecordGroupGSortB);
- validator.process(mRecordNoGroup);
- validator.process(mRecordNoGroup2);
- validator.process(mRecordNoGroupSortA);
- assertTrue(mRecordGroupGSortA.getTopicImportance() == IMPORTANCE_MAX);
- assertTrue(mRecordGroupGSortB.getTopicImportance() == IMPORTANCE_MAX);
- assertTrue(mRecordNoGroup.getTopicImportance() == IMPORTANCE_HIGH);
- assertTrue(mRecordNoGroup2.getTopicImportance() == IMPORTANCE_LOW);
- assertTrue(mRecordNoGroupSortA.getTopicImportance() == IMPORTANCE_UNSPECIFIED);
- }
}
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 46de201..9ac4dbf 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -162,78 +162,6 @@
}
},
- new Test("with topic Hello") {
- public void run() {
- Notification.BigTextStyle bigText = new Notification.BigTextStyle();
- bigText.bigText("FgBHreherhethethethe\ntwetwrterter\netetweterteryetry");
- Notification n = new Notification.Builder(NotificationTestList.this)
- .setSmallIcon(R.drawable.icon1)
- .setStyle(bigText)
- .setWhen(mActivityCreateTime)
- .setContentTitle("hihi")
- .setContentText("This is a notification!!!")
- .setContentIntent(makeIntent2())
- .setTopic(new Notification.Topic("hello", "Hello"))
- .build();
-
- mNM.notify(70, n);
- }
- },
-
- new Test("with topic GoodBye") {
- public void run() {
- Notification.BigPictureStyle picture = new Notification.BigPictureStyle();
- picture.bigPicture(BitmapFactory.decodeResource(getResources(),
- R.id.large_icon_pineapple2));
- Notification n = new Notification.Builder(NotificationTestList.this)
- .setSmallIcon(R.drawable.icon1)
- .setWhen(mActivityCreateTime)
- .setContentTitle("byebye")
- .setContentText("This is a notification!!!")
- .setContentIntent(makeIntent2())
- .setTopic(new Notification.Topic("bye", "Goodbye"))
- .setStyle(picture)
- .build();
-
- mNM.notify(71, n);
- }
- },
- new Test("with topic Bananas") {
- public void run() {
- Notification.BigTextStyle bigText = new Notification.BigTextStyle();
- bigText.bigText("bananas are great\nso tasty\nyum\nyum\nyum\n");
- Notification n = new Notification.Builder(NotificationTestList.this)
- .setSmallIcon(R.drawable.icon1)
- .setStyle(bigText)
- .setWhen(mActivityCreateTime)
- .setContentTitle("bananananana")
- .setContentText("This is a banana!!!")
- .setContentIntent(makeIntent2())
- .setTopic(new Notification.Topic("bananas", "Bananas"))
- .build();
-
- mNM.notify(72, n);
- }
- },
-
- new Test("with delete intent") {
- public void run() {
- Notification.BigTextStyle bigText = new Notification.BigTextStyle();
- bigText.bigText("bananas are great\nso tasty\nyum\nyum\nyum\n");
- Notification n = new Notification.Builder(NotificationTestList.this)
- .setSmallIcon(R.drawable.icon1)
- .setStyle(bigText)
- .setWhen(mActivityCreateTime)
- .setContentTitle("bananananana")
- .setContentText("This is a banana!!!")
- .setTopic(new Notification.Topic("bananas", "Bananas"))
- .setDeleteIntent(makeIntent2())
- .build();
-
- mNM.notify(73, n);
- }
- },
-
new Test("Is blocked?") {
public void run() {
Toast.makeText(NotificationTestList.this,
@@ -242,18 +170,10 @@
}
},
- new Test("Topic banana importance?") {
+ new Test("importance?") {
public void run() {
Toast.makeText(NotificationTestList.this,
- "bananas importance? " + mNM.getImportance("bananas"),
- Toast.LENGTH_LONG).show();
- }
- },
-
- new Test("Topic garbage importance?") {
- public void run() {
- Toast.makeText(NotificationTestList.this,
- "garbage importance? " + mNM.getImportance("garbage"),
+ "importance? " + mNM.getImportance(),
Toast.LENGTH_LONG).show();
}
},
diff --git a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
index 94f3f54..4901f72 100644
--- a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
+++ b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
@@ -45,10 +45,4 @@
public static void dispatchOnPreDraw(View view) {
view.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
}
-
- public static void detachFromWindow(View view) {
- if (view != null) {
- view.dispatchDetachedFromWindow();
- }
- }
}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_RunQueue_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_RunQueue_Delegate.java
deleted file mode 100644
index 51b42a6..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_RunQueue_Delegate.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of
- * {@link ViewRootImpl.RunQueue}
- *
- * Through the layoutlib_create tool, the original methods of ViewRootImpl.RunQueue have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class ViewRootImpl_RunQueue_Delegate {
-
- @LayoutlibDelegate
- /*package*/ static void postDelayed(ViewRootImpl.RunQueue thisQueue, Runnable action, long
- delayMillis) {
- // The actual RunQueue is never run and therefore never cleared. This method avoids
- // runnables to be added to the RunQueue so they do not leak resources.
- }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
index fea633e..2ac212c 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
@@ -208,9 +208,6 @@
@Override
public void dispose() {
- if (mSession != null) {
- mSession.dispose();
- }
}
/*package*/ BridgeRenderSession(RenderSessionImpl scene, Result lastResult) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 99af226..ec50cfe 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -1396,21 +1396,4 @@
public RenderSession getSession() {
return mScene;
}
-
- public void dispose() {
- AttachInfo_Accessor.detachFromWindow(mViewRoot);
- if (mCanvas != null) {
- mCanvas.release();
- mCanvas = null;
- }
- if (mViewInfoList != null) {
- mViewInfoList.clear();
- }
- if (mSystemViewInfoList != null) {
- mSystemViewInfoList.clear();
- }
- mImage = null;
- mViewRoot = null;
- mContentRoot = null;
- }
}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index 6b23da7..fe16a3e 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -291,6 +291,7 @@
@Test
public void testActivity() throws ClassNotFoundException {
renderAndVerify("activity.xml", "activity.png");
+
}
/** Test allwidgets.xml */
@@ -430,8 +431,6 @@
ImageUtils.requireSimilar(goldenImagePath, session.getImage());
} catch (IOException e) {
getLogger().error(e, e.getMessage());
- } finally {
- session.dispose();
}
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 1f4341c..9e390f6 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -183,7 +183,6 @@
"android.view.View#getWindowToken",
"android.view.View#isInEditMode",
"android.view.ViewRootImpl#isInTouchMode",
- "android.view.ViewRootImpl$RunQueue#postDelayed",
"android.view.WindowManagerGlobal#getWindowManagerService",
"android.view.inputmethod.InputMethodManager#getInstance",
"android.view.MenuInflater#registerMenu",
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 31da670..ed12bdf 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -331,6 +331,7 @@
*/
public static class InformationElement {
public static final int EID_SSID = 0;
+ public static final int EID_TIM = 5;
public static final int EID_BSS_LOAD = 11;
public static final int EID_RSN = 48;
public static final int EID_HT_OPERATION = 61;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index cce8386..ddd8f43 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -403,6 +403,15 @@
/**
* @hide
+ * The number of beacon intervals between Delivery Traffic Indication Maps (DTIM)
+ * This value is populated from scan results that contain Beacon Frames, which are infrequent.
+ * The value is not guaranteed to be set or current (Although it SHOULDNT change once set)
+ * Valid values are from 1 - 255. Initialized here as 0, use this to check if set.
+ */
+ public int dtimInterval = 0;
+
+ /**
+ * @hide
* Uid of app creating the configuration
*/
@SystemApi
@@ -1298,6 +1307,7 @@
lastUpdateUid = -1;
creatorUid = -1;
shared = true;
+ dtimInterval = 0;
}
/**
@@ -2044,4 +2054,4 @@
config.allowedKeyManagement.set(in.readInt());
return config;
}
-}
\ No newline at end of file
+}